blob: c5b675d16188b85ce122d04c2a3c5c529488905e [file] [log] [blame]
Jeremy Hylton1afc1692008-06-18 20:49:58 +00001"""Exception classes raised by urllib.
2
Andrew Svetlovf7a17b42012-12-25 16:47:37 +02003The base exception class is URLError, which inherits from OSError. It
Jeremy Hylton1afc1692008-06-18 20:49:58 +00004doesn'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
Senthil Kumaran6c5bd402011-11-01 23:20:31 +080016__all__ = ['URLError', 'HTTPError', 'ContentTooShortError']
17
18
Jeremy Hylton1afc1692008-06-18 20:49:58 +000019# do these error classes make sense?
Andrew Svetlovf7a17b42012-12-25 16:47:37 +020020# make sure all of the OSError stuff is overridden. we just want to be
Jeremy Hylton1afc1692008-06-18 20:49:58 +000021# subtypes.
22
Andrew Svetlovf7a17b42012-12-25 16:47:37 +020023class URLError(OSError):
24 # URLError is a sub-type of OSError, but it doesn't share any of
Jeremy Hylton1afc1692008-06-18 20:49:58 +000025 # 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
Facundo Batista244afcf2015-04-22 18:35:54 -030038
Jeremy Hylton1afc1692008-06-18 20:49:58 +000039class 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
Facundo Batista244afcf2015-04-22 18:35:54 -030059 def __repr__(self):
60 return '<HTTPError %s: %r>' % (self.code, self.msg)
61
Jason R. Coombsaa204db2011-11-07 10:50:32 -050062 # 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
Senthil Kumaran5962cce2012-12-10 02:09:35 -080068 @property
69 def headers(self):
70 return self.hdrs
71
72 @headers.setter
73 def headers(self, headers):
74 self.hdrs = headers
75
Facundo Batista244afcf2015-04-22 18:35:54 -030076
Jeremy Hylton1afc1692008-06-18 20:49:58 +000077class ContentTooShortError(URLError):
Facundo Batista244afcf2015-04-22 18:35:54 -030078 """Exception raised when downloaded size does not match content-length."""
Jeremy Hylton1afc1692008-06-18 20:49:58 +000079 def __init__(self, message, content):
80 URLError.__init__(self, message)
81 self.content = content