Support Client-Level Exception Handlers for httpx.Client and httpx.AsyncClient #3701
Replies: 1 comment
|
In Here is how you can achieve centralized, inheritance-aware exception handling today in both sync and async, along with the core architectural considerations around streaming and return values. Solution 1: Custom Transport Middleware (Recommended for network/transport errors)
import logging
from typing import Callable, Type
import httpx
logger = logging.getLogger(__name__)
class ExceptionHandlerTransport(httpx.HTTPTransport):
def __init__(self, handlers: dict[Type[Exception], Callable[[Exception, httpx.Request], httpx.Response | None]] = None, **kwargs):
super().__init__(**kwargs)
self.handlers = handlers or {}
def _resolve_handler(self, exc: Exception):
# MRO-based matching: find the most specific registered exception type
for cls in type(exc).mro():
if cls in self.handlers:
return self.handlers[cls]
return None
def handle_request(self, request: httpx.Request) -> httpx.Response:
try:
return super().handle_request(request)
except Exception as exc:
handler = self._resolve_handler(exc)
if handler is not None:
res = handler(exc, request)
if isinstance(res, httpx.Response):
return res
raise
# Usage:
def on_timeout(exc: Exception, request: httpx.Request):
logger.warning(f"Timeout on {request.url}: {exc}")
# Can return a synthetic fallback response or re-raise
return httpx.Response(status_code=504, content=b"Gateway Timeout (Handled)")
client = httpx.Client(
transport=ExceptionHandlerTransport(
handlers={
httpx.TimeoutException: on_timeout,
}
)
)
resp = client.get("https://example.com")For async, implement the exact same wrapper on Solution 2: Overriding
|
Uh oh!
There was an error while loading. Please reload this page.
🚀 Feature Request: Client-Level Exception Handlers for
httpx.Clientandhttpx.AsyncClientProblem Statement
Currently,
httpx.Clientandhttpx.AsyncClientdo not support registering custom exception handlers at the client level.Developers are forced to wrap every request call with repetitive
try/exceptblocks whenever consistent error handling is required.This results in:
In many real-world scenarios, applications need uniform exception management across all outgoing HTTP calls from a shared client instance.
Proposed Solution
Introduce the ability to register custom exception handlers at the client level, allowing centralized and automatic handling of all exceptions raised during requests.
Key aspects of the proposed behavior:
Example Use Case
This pattern ensures that all requests from a client share the same consistent error handling behavior without requiring per-call wrappers.
Expected Behavior
client.request(),client.get(),client.post(), etc.httpx.ReadTimeout) take precedence over general ones (e.g.,httpx.RequestError).Benefits
Discussion Points
exception_handlersbe modifiable post client initialization?References & Inspiration
exception_handlers), aiohttp middlewares, and requests-hooks.All reactions