Home | History | Annotate | Download | only in urllib
      1 """Exception classes raised by urllib.
      2 
      3 The base exception class is URLError, which inherits from OSError.  It
      4 doesn't define any behavior of its own, but is the base class for all
      5 exceptions defined in this package.
      6 
      7 HTTPError is an exception class that is also a valid HTTP response
      8 instance.  It behaves this way because HTTP protocol errors are valid
      9 responses, with a status code, headers, and a body.  In some contexts,
     10 an application may want to handle an exception like a regular
     11 response.
     12 """
     13 
     14 import urllib.response
     15 
     16 __all__ = ['URLError', 'HTTPError', 'ContentTooShortError']
     17 
     18 
     19 # do these error classes make sense?
     20 # make sure all of the OSError stuff is overridden.  we just want to be
     21 # subtypes.
     22 
     23 class URLError(OSError):
     24     # URLError is a sub-type of OSError, but it doesn't share any of
     25     # the implementation.  need to override __init__ and __str__.
     26     # It sets self.args for compatibility with other EnvironmentError
     27     # subclasses, but args doesn't have the typical format with errno in
     28     # slot 0 and strerror in slot 1.  This may be better than nothing.
     29     def __init__(self, reason, filename=None):
     30         self.args = reason,
     31         self.reason = reason
     32         if filename is not None:
     33             self.filename = filename
     34 
     35     def __str__(self):
     36         return '<urlopen error %s>' % self.reason
     37 
     38 
     39 class HTTPError(URLError, urllib.response.addinfourl):
     40     """Raised when HTTP error occurs, but also acts like non-error return"""
     41     __super_init = urllib.response.addinfourl.__init__
     42 
     43     def __init__(self, url, code, msg, hdrs, fp):
     44         self.code = code
     45         self.msg = msg
     46         self.hdrs = hdrs
     47         self.fp = fp
     48         self.filename = url
     49         # The addinfourl classes depend on fp being a valid file
     50         # object.  In some cases, the HTTPError may not have a valid
     51         # file object.  If this happens, the simplest workaround is to
     52         # not initialize the base classes.
     53         if fp is not None:
     54             self.__super_init(fp, hdrs, url, code)
     55 
     56     def __str__(self):
     57         return 'HTTP Error %s: %s' % (self.code, self.msg)
     58 
     59     def __repr__(self):
     60         return '<HTTPError %s: %r>' % (self.code, self.msg)
     61 
     62     # since URLError specifies a .reason attribute, HTTPError should also
     63     #  provide this attribute. See issue13211 for discussion.
     64     @property
     65     def reason(self):
     66         return self.msg
     67 
     68     @property
     69     def headers(self):
     70         return self.hdrs
     71 
     72     @headers.setter
     73     def headers(self, headers):
     74         self.hdrs = headers
     75 
     76 
     77 class ContentTooShortError(URLError):
     78     """Exception raised when downloaded size does not match content-length."""
     79     def __init__(self, message, content):
     80         URLError.__init__(self, message)
     81         self.content = content
     82