error.py 2.57 KB
Newer Older
1 2
"""Exception classes raised by urllib.

3
The base exception class is URLError, which inherits from OSError.  It
4 5 6 7 8 9 10 11 12 13 14 15
doesn't define any behavior of its own, but is the base class for all
exceptions defined in this package.

HTTPError is an exception class that is also a valid HTTP response
instance.  It behaves this way because HTTP protocol errors are valid
responses, with a status code, headers, and a body.  In some contexts,
an application may want to handle an exception like a regular
response.
"""

import urllib.response

16 17 18
__all__ = ['URLError', 'HTTPError', 'ContentTooShortError']


19 20
class URLError(OSError):
    # 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 24 25 26 27 28 29 30 31 32 33
    # subclasses, but args doesn't have the typical format with errno in
    # slot 0 and strerror in slot 1.  This may be better than nothing.
    def __init__(self, reason, filename=None):
        self.args = reason,
        self.reason = reason
        if filename is not None:
            self.filename = filename

    def __str__(self):
        return '<urlopen error %s>' % self.reason

34

35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
class HTTPError(URLError, urllib.response.addinfourl):
    """Raised when HTTP error occurs, but also acts like non-error return"""
    __super_init = urllib.response.addinfourl.__init__

    def __init__(self, url, code, msg, hdrs, fp):
        self.code = code
        self.msg = msg
        self.hdrs = hdrs
        self.fp = fp
        self.filename = url
        # The addinfourl classes depend on fp being a valid file
        # object.  In some cases, the HTTPError may not have a valid
        # file object.  If this happens, the simplest workaround is to
        # not initialize the base classes.
        if fp is not None:
            self.__super_init(fp, hdrs, url, code)

    def __str__(self):
        return 'HTTP Error %s: %s' % (self.code, self.msg)

55 56 57
    def __repr__(self):
        return '<HTTPError %s: %r>' % (self.code, self.msg)

58 59 60 61 62 63
    # since URLError specifies a .reason attribute, HTTPError should also
    #  provide this attribute. See issue13211 for discussion.
    @property
    def reason(self):
        return self.msg

64 65 66 67 68 69 70 71
    @property
    def headers(self):
        return self.hdrs

    @headers.setter
    def headers(self, headers):
        self.hdrs = headers

72

73
class ContentTooShortError(URLError):
74
    """Exception raised when downloaded size does not match content-length."""
75 76 77
    def __init__(self, message, content):
        URLError.__init__(self, message)
        self.content = content