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