HTTP error middleware.
Should be positioned as late as possible and before rate limiter middlewares
(if any) in the client middlewares list.
Responses are handled differently based on their HTTP status:
Status |
Measures |
2XX |
Return response. |
3XX |
Raise aiohttp.ClientResponseError . |
4XX |
Raise aiohttp.ClientResponseError . |
429 |
Exponential retries (2^n). |
5XX |
Exponential retries (2^n). |
Conn |
Exponential retries (2^n). |
Example:
Parameters:
Name |
Type |
Description |
Default |
max_retries
|
int
|
Number of retries to perform before giving up.
|
3
|
Raises:
Type |
Description |
ClientResponseError
|
When retries have exhausted.
|
Source code in pulsefire/middlewares.py
| def http_error_middleware(max_retries: int = 3):
"""HTTP error middleware.
Should be positioned as late as possible and before rate limiter middlewares
(if any) in the client middlewares list.
Responses are handled differently based on their HTTP status:
| Status | Measures |
| ------ | ------------------------------------- |
| 2XX | Return response. |
| 3XX | Raise `aiohttp.ClientResponseError`. |
| 4XX | Raise `aiohttp.ClientResponseError`. |
| 429 | Exponential retries (2^n). |
| 5XX | Exponential retries (2^n). |
| Conn | Exponential retries (2^n). |
Example:
```python
http_error_middleware(3)
```
Parameters:
max_retries: Number of retries to perform before giving up.
Raises:
aiohttp.ClientResponseError: When retries have exhausted.
"""
def constructor(next: MiddlewareCallable):
async def middleware(invocation: Invocation):
last_response: aiohttp.ClientResponse | None = None
last_connexc: aiohttp.ClientConnectionError | asyncio.TimeoutError = asyncio.TimeoutError()
for attempt in range(max_retries + 1):
if attempt:
await asyncio.sleep(2 ** attempt)
try:
response: aiohttp.ClientResponse = await next(invocation)
except (asyncio.TimeoutError, aiohttp.ClientConnectionError) as connexc:
last_connexc = connexc
continue
last_response = response
if 300 > response.status >= 200:
return response
if not (response.status == 429 or response.status >= 500):
response.raise_for_status()
else:
if last_response:
last_response.raise_for_status()
raise last_connexc
return middleware
return constructor
|