1import logging
2import typing as t
3
4from starlette.middleware.errors import (
5 ServerErrorMiddleware as StarletteServerErrorMiddleware,
6)
7from starlette.types import ASGIApp
8
9from connexion.exceptions import InternalServerError
10from connexion.lifecycle import ConnexionRequest, ConnexionResponse
11from connexion.middleware.exceptions import connexion_wrapper
12from connexion.types import MaybeAwaitable
13
14logger = logging.getLogger(__name__)
15
16
17class ServerErrorMiddleware(StarletteServerErrorMiddleware):
18 """Subclass of starlette ServerErrorMiddleware to change handling of Unhandled Server
19 exceptions to existing connexion behavior."""
20
21 def __init__(
22 self,
23 next_app: ASGIApp,
24 handler: t.Optional[
25 t.Callable[[ConnexionRequest, Exception], MaybeAwaitable[ConnexionResponse]]
26 ] = None,
27 ):
28 handler = connexion_wrapper(handler) if handler else None
29 super().__init__(next_app, handler=handler)
30
31 @staticmethod
32 @connexion_wrapper
33 def error_response(_request: ConnexionRequest, exc: Exception) -> ConnexionResponse:
34 """Default handler for any unhandled Exception"""
35 logger.error("%r", exc, exc_info=exc)
36 return InternalServerError().to_problem()