Jeremy Hylton | 1afc169 | 2008-06-18 20:49:58 +0000 | [diff] [blame] | 1 | """Exception classes raised by urllib. |
| 2 | |
| 3 | The base exception class is URLError, which inherits from IOError. 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 | # do these error classes make sense? |
| 17 | # make sure all of the IOError stuff is overridden. we just want to be |
| 18 | # subtypes. |
| 19 | |
| 20 | class URLError(IOError): |
| 21 | # URLError is a sub-type of IOError, but it doesn't share any of |
| 22 | # the implementation. need to override __init__ and __str__. |
| 23 | # It sets self.args for compatibility with other EnvironmentError |
| 24 | # subclasses, but args doesn't have the typical format with errno in |
| 25 | # slot 0 and strerror in slot 1. This may be better than nothing. |
| 26 | def __init__(self, reason, filename=None): |
| 27 | self.args = reason, |
| 28 | self.reason = reason |
| 29 | if filename is not None: |
| 30 | self.filename = filename |
| 31 | |
| 32 | def __str__(self): |
| 33 | return '<urlopen error %s>' % self.reason |
| 34 | |
| 35 | class 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 | |
Jason R. Coombs | aa204db | 2011-11-07 10:50:32 -0500 | [diff] [blame] | 55 | # since URLError specifies a .reason attribute, HTTPError should also |
| 56 | # provide this attribute. See issue13211 for discussion. |
| 57 | @property |
| 58 | def reason(self): |
| 59 | return self.msg |
| 60 | |
Jeremy Hylton | 1afc169 | 2008-06-18 20:49:58 +0000 | [diff] [blame] | 61 | # exception raised when downloaded size does not match content-length |
| 62 | class ContentTooShortError(URLError): |
| 63 | def __init__(self, message, content): |
| 64 | URLError.__init__(self, message) |
| 65 | self.content = content |