]>
jfr.im git - yt-dlp.git/blob - yt_dlp/networking/exceptions.py
1 from __future__
import annotations
6 from ..utils
import YoutubeDLError
, deprecation_warning
8 if typing
.TYPE_CHECKING
:
9 from .common
import RequestHandler
, Response
12 class RequestError(YoutubeDLError
):
15 msg
: str |
None = None,
16 cause
: Exception |
str |
None = None,
17 handler
: RequestHandler
= None
19 self
.handler
= handler
26 class UnsupportedRequest(RequestError
):
27 """raised when a handler cannot handle a request"""
31 class NoSupportingHandlers(RequestError
):
32 """raised when no handlers can support a request for various reasons"""
34 def __init__(self
, unsupported_errors
: list[UnsupportedRequest
], unexpected_errors
: list[Exception]):
35 self
.unsupported_errors
= unsupported_errors
or []
36 self
.unexpected_errors
= unexpected_errors
or []
38 # Print a quick summary of the errors
40 for err
in unsupported_errors
:
41 err_handler_map
.setdefault(err
.msg
, []).append(err
.handler
.RH_NAME
)
43 reason_str
= ', '.join([f
'{msg} ({", ".join(handlers)})' for msg
, handlers
in err_handler_map
.items()])
45 reason_str
= ' + '.join(filter(None, [reason_str
, f
'{len(unexpected_errors)} unexpected error(s)']))
47 err_str
= 'Unable to handle request'
49 err_str
+= f
': {reason_str}'
51 super().__init
__(msg
=err_str
)
54 class TransportError(RequestError
):
55 """Network related errors"""
58 class HTTPError(RequestError
):
59 def __init__(self
, response
: Response
, redirect_loop
=False):
60 self
.response
= response
61 self
.status
= response
.status
62 self
.reason
= response
.reason
63 self
.redirect_loop
= redirect_loop
64 msg
= f
'HTTP Error {response.status}: {response.reason}'
66 msg
+= ' (redirect loop detected)'
68 super().__init
__(msg
=msg
)
74 return f
'<HTTPError {self.status}: {self.reason}>'
77 class IncompleteRead(TransportError
):
78 def __init__(self
, partial
: int, expected
: int |
None = None, **kwargs
):
79 self
.partial
= partial
80 self
.expected
= expected
81 msg
= f
'{partial} bytes read'
82 if expected
is not None:
83 msg
+= f
', {expected} more expected'
85 super().__init
__(msg
=msg
, **kwargs
)
88 return f
'<IncompleteRead: {self.msg}>'
91 class SSLError(TransportError
):
95 class CertificateVerifyError(SSLError
):
96 """Raised when certificate validated has failed"""
100 class ProxyError(TransportError
):
104 class _CompatHTTPError(urllib
.error
.HTTPError
, HTTPError
):
106 Provides backwards compatibility with urllib.error.HTTPError.
107 Do not use this class directly, use HTTPError instead.
110 def __init__(self
, http_error
: HTTPError
):
112 url
=http_error
.response
.url
,
113 code
=http_error
.status
,
115 hdrs
=http_error
.response
.headers
,
116 fp
=http_error
.response
118 self
._closer
.close_called
= True # Disable auto close
119 self
._http
_error
= http_error
120 HTTPError
.__init
__(self
, http_error
.response
, redirect_loop
=http_error
.redirect_loop
)
124 return self
._http
_error
.status
127 def status(self
, value
):
132 return self
._http
_error
.reason
135 def reason(self
, value
):
140 deprecation_warning('HTTPError.headers is deprecated, use HTTPError.response.headers instead')
141 return self
._http
_error
.response
.headers
144 def headers(self
, value
):
148 deprecation_warning('HTTPError.info() is deprecated, use HTTPError.response.headers instead')
149 return self
.response
.headers
152 deprecation_warning('HTTPError.getcode is deprecated, use HTTPError.status instead')
156 deprecation_warning('HTTPError.geturl is deprecated, use HTTPError.response.url instead')
157 return self
.response
.url
161 deprecation_warning('HTTPError.code is deprecated, use HTTPError.status instead')
165 def code(self
, value
):
170 deprecation_warning('HTTPError.url is deprecated, use HTTPError.response.url instead')
171 return self
.response
.url
174 def url(self
, value
):
179 deprecation_warning('HTTPError.hdrs is deprecated, use HTTPError.response.headers instead')
180 return self
.response
.headers
183 def hdrs(self
, value
):
188 deprecation_warning('HTTPError.filename is deprecated, use HTTPError.response.url instead')
189 return self
.response
.url
192 def filename(self
, value
):
195 def __getattr__(self
, name
):
196 # File operations are passed through the response.
197 # Warn for some commonly used ones
198 passthrough_warnings
= {
199 'read': 'response.read()',
200 # technically possibly due to passthrough, but we should discourage this
201 'get_header': 'response.get_header()',
202 'readable': 'response.readable()',
203 'closed': 'response.closed',
204 'tell': 'response.tell()',
206 if name
in passthrough_warnings
:
207 deprecation_warning(f
'HTTPError.{name} is deprecated, use HTTPError.{passthrough_warnings[name]} instead')
208 return super().__getattr
__(name
)
211 return str(self
._http
_error
)
214 return repr(self
._http
_error
)
217 network_exceptions
= (HTTPError
, TransportError
)