Coverage for /pythoncovmergedfiles/medio/medio/src/aiohttp/aiohttp/client_exceptions.py: 57%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""HTTP related errors."""
3import asyncio
4from typing import TYPE_CHECKING, Optional, Tuple, Union
6from multidict import MultiMapping
8from .typedefs import StrOrURL
10if TYPE_CHECKING:
11 import ssl
13 SSLContext = ssl.SSLContext
14else:
15 try:
16 import ssl
18 SSLContext = ssl.SSLContext
19 except ImportError: # pragma: no cover
20 ssl = SSLContext = None # type: ignore[assignment]
22if TYPE_CHECKING:
23 from .client_reqrep import ClientResponse, ConnectionKey, Fingerprint, RequestInfo
24 from .http_parser import RawResponseMessage
25else:
26 RequestInfo = ClientResponse = ConnectionKey = RawResponseMessage = None
28__all__ = (
29 "ClientError",
30 "ClientConnectionError",
31 "ClientConnectionResetError",
32 "ClientOSError",
33 "ClientConnectorError",
34 "ClientProxyConnectionError",
35 "ClientSSLError",
36 "ClientConnectorDNSError",
37 "ClientConnectorSSLError",
38 "ClientConnectorCertificateError",
39 "ConnectionTimeoutError",
40 "SocketTimeoutError",
41 "ServerConnectionError",
42 "ServerTimeoutError",
43 "ServerDisconnectedError",
44 "ServerFingerprintMismatch",
45 "ClientResponseError",
46 "ClientHttpProxyError",
47 "WSServerHandshakeError",
48 "ContentTypeError",
49 "ClientPayloadError",
50 "InvalidURL",
51 "InvalidUrlClientError",
52 "RedirectClientError",
53 "NonHttpUrlClientError",
54 "InvalidUrlRedirectClientError",
55 "NonHttpUrlRedirectClientError",
56 "WSMessageTypeError",
57)
60class ClientError(Exception):
61 """Base class for client connection errors."""
64class ClientResponseError(ClientError):
65 """Base class for exceptions that occur after getting a response.
67 request_info: An instance of RequestInfo.
68 history: A sequence of responses, if redirects occurred.
69 status: HTTP status code.
70 message: Error message.
71 headers: Response headers.
72 """
74 def __init__(
75 self,
76 request_info: RequestInfo,
77 history: Tuple[ClientResponse, ...],
78 *,
79 status: Optional[int] = None,
80 message: str = "",
81 headers: Optional[MultiMapping[str]] = None,
82 ) -> None:
83 self.request_info = request_info
84 if status is not None:
85 self.status = status
86 else:
87 self.status = 0
88 self.message = message
89 self.headers = headers
90 self.history = history
91 self.args = (request_info, history)
93 def __str__(self) -> str:
94 return "{}, message={!r}, url={!r}".format(
95 self.status,
96 self.message,
97 str(self.request_info.real_url),
98 )
100 def __repr__(self) -> str:
101 args = f"{self.request_info!r}, {self.history!r}"
102 if self.status != 0:
103 args += f", status={self.status!r}"
104 if self.message != "":
105 args += f", message={self.message!r}"
106 if self.headers is not None:
107 args += f", headers={self.headers!r}"
108 return f"{type(self).__name__}({args})"
111class ContentTypeError(ClientResponseError):
112 """ContentType found is not valid."""
115class WSServerHandshakeError(ClientResponseError):
116 """websocket server handshake error."""
119class ClientHttpProxyError(ClientResponseError):
120 """HTTP proxy error.
122 Raised in :class:`aiohttp.connector.TCPConnector` if
123 proxy responds with status other than ``200 OK``
124 on ``CONNECT`` request.
125 """
128class TooManyRedirects(ClientResponseError):
129 """Client was redirected too many times."""
132class ClientConnectionError(ClientError):
133 """Base class for client socket errors."""
136class ClientConnectionResetError(ClientConnectionError, ConnectionResetError):
137 """ConnectionResetError"""
140class ClientOSError(ClientConnectionError, OSError):
141 """OSError error."""
144class ClientConnectorError(ClientOSError):
145 """Client connector error.
147 Raised in :class:`aiohttp.connector.TCPConnector` if
148 a connection can not be established.
149 """
151 def __init__(self, connection_key: ConnectionKey, os_error: OSError) -> None:
152 self._conn_key = connection_key
153 self._os_error = os_error
154 super().__init__(os_error.errno, os_error.strerror)
155 self.args = (connection_key, os_error)
157 @property
158 def os_error(self) -> OSError:
159 return self._os_error
161 @property
162 def host(self) -> str:
163 return self._conn_key.host
165 @property
166 def port(self) -> Optional[int]:
167 return self._conn_key.port
169 @property
170 def ssl(self) -> Union[SSLContext, bool, "Fingerprint"]:
171 return self._conn_key.ssl
173 def __str__(self) -> str:
174 return "Cannot connect to host {0.host}:{0.port} ssl:{1} [{2}]".format(
175 self, "default" if self.ssl is True else self.ssl, self.strerror
176 )
178 # OSError.__reduce__ does too much black magick
179 __reduce__ = BaseException.__reduce__
182class ClientConnectorDNSError(ClientConnectorError):
183 """DNS resolution failed during client connection.
185 Raised in :class:`aiohttp.connector.TCPConnector` if
186 DNS resolution fails.
187 """
190class ClientProxyConnectionError(ClientConnectorError):
191 """Proxy connection error.
193 Raised in :class:`aiohttp.connector.TCPConnector` if
194 connection to proxy can not be established.
195 """
198class UnixClientConnectorError(ClientConnectorError):
199 """Unix connector error.
201 Raised in :py:class:`aiohttp.connector.UnixConnector`
202 if connection to unix socket can not be established.
203 """
205 def __init__(
206 self, path: str, connection_key: ConnectionKey, os_error: OSError
207 ) -> None:
208 self._path = path
209 super().__init__(connection_key, os_error)
211 @property
212 def path(self) -> str:
213 return self._path
215 def __str__(self) -> str:
216 return "Cannot connect to unix socket {0.path} ssl:{1} [{2}]".format(
217 self, "default" if self.ssl is True else self.ssl, self.strerror
218 )
221class ServerConnectionError(ClientConnectionError):
222 """Server connection errors."""
225class ServerDisconnectedError(ServerConnectionError):
226 """Server disconnected."""
228 def __init__(self, message: Union[RawResponseMessage, str, None] = None) -> None:
229 if message is None:
230 message = "Server disconnected"
232 self.args = (message,)
233 self.message = message
236class ServerTimeoutError(ServerConnectionError, asyncio.TimeoutError):
237 """Server timeout error."""
240class ConnectionTimeoutError(ServerTimeoutError):
241 """Connection timeout error."""
244class SocketTimeoutError(ServerTimeoutError):
245 """Socket timeout error."""
248class ServerFingerprintMismatch(ServerConnectionError):
249 """SSL certificate does not match expected fingerprint."""
251 def __init__(self, expected: bytes, got: bytes, host: str, port: int) -> None:
252 self.expected = expected
253 self.got = got
254 self.host = host
255 self.port = port
256 self.args = (expected, got, host, port)
258 def __repr__(self) -> str:
259 return "<{} expected={!r} got={!r} host={!r} port={!r}>".format(
260 self.__class__.__name__, self.expected, self.got, self.host, self.port
261 )
264class ClientPayloadError(ClientError):
265 """Response payload error."""
268class InvalidURL(ClientError, ValueError):
269 """Invalid URL.
271 URL used for fetching is malformed, e.g. it doesn't contains host
272 part.
273 """
275 # Derive from ValueError for backward compatibility
277 def __init__(self, url: StrOrURL, description: Union[str, None] = None) -> None:
278 # The type of url is not yarl.URL because the exception can be raised
279 # on URL(url) call
280 self._url = url
281 self._description = description
283 if description:
284 super().__init__(url, description)
285 else:
286 super().__init__(url)
288 @property
289 def url(self) -> StrOrURL:
290 return self._url
292 @property
293 def description(self) -> "str | None":
294 return self._description
296 def __repr__(self) -> str:
297 return f"<{self.__class__.__name__} {self}>"
299 def __str__(self) -> str:
300 if self._description:
301 return f"{self._url} - {self._description}"
302 return str(self._url)
305class InvalidUrlClientError(InvalidURL):
306 """Invalid URL client error."""
309class RedirectClientError(ClientError):
310 """Client redirect error."""
313class NonHttpUrlClientError(ClientError):
314 """Non http URL client error."""
317class InvalidUrlRedirectClientError(InvalidUrlClientError, RedirectClientError):
318 """Invalid URL redirect client error."""
321class NonHttpUrlRedirectClientError(NonHttpUrlClientError, RedirectClientError):
322 """Non http URL redirect client error."""
325class ClientSSLError(ClientConnectorError):
326 """Base error for ssl.*Errors."""
329if ssl is not None:
330 cert_errors = (ssl.CertificateError,)
331 cert_errors_bases = (
332 ClientSSLError,
333 ssl.CertificateError,
334 )
336 ssl_errors = (ssl.SSLError,)
337 ssl_error_bases = (ClientSSLError, ssl.SSLError)
338else: # pragma: no cover
339 cert_errors = tuple() # type: ignore[unreachable]
340 cert_errors_bases = (
341 ClientSSLError,
342 ValueError,
343 )
345 ssl_errors = tuple()
346 ssl_error_bases = (ClientSSLError,)
349class ClientConnectorSSLError(*ssl_error_bases): # type: ignore[misc]
350 """Response ssl error."""
353class ClientConnectorCertificateError(*cert_errors_bases): # type: ignore[misc]
354 """Response certificate error."""
356 def __init__(
357 self, connection_key: ConnectionKey, certificate_error: Exception
358 ) -> None:
359 self._conn_key = connection_key
360 self._certificate_error = certificate_error
361 self.args = (connection_key, certificate_error)
363 @property
364 def certificate_error(self) -> Exception:
365 return self._certificate_error
367 @property
368 def host(self) -> str:
369 return self._conn_key.host
371 @property
372 def port(self) -> Optional[int]:
373 return self._conn_key.port
375 @property
376 def ssl(self) -> bool:
377 return self._conn_key.is_ssl
379 def __str__(self) -> str:
380 return (
381 "Cannot connect to host {0.host}:{0.port} ssl:{0.ssl} "
382 "[{0.certificate_error.__class__.__name__}: "
383 "{0.certificate_error.args}]".format(self)
384 )
387class WSMessageTypeError(TypeError):
388 """WebSocket message type is not valid."""