Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/connexion/middleware/exceptions.py: 53%

32 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2023-03-26 06:12 +0000

1import logging 

2 

3from starlette.exceptions import ExceptionMiddleware as StarletteExceptionMiddleware 

4from starlette.exceptions import HTTPException 

5from starlette.requests import Request as StarletteRequest 

6from starlette.responses import Response 

7from starlette.types import ASGIApp, Receive, Scope, Send 

8 

9from connexion.exceptions import InternalServerError, ProblemException, problem 

10 

11logger = logging.getLogger(__name__) 

12 

13 

14class ExceptionMiddleware(StarletteExceptionMiddleware): 

15 """Subclass of starlette ExceptionMiddleware to change handling of HTTP exceptions to 

16 existing connexion behavior.""" 

17 

18 def __init__(self, next_app: ASGIApp, *args, **kwargs): 

19 super().__init__(next_app) 

20 self.add_exception_handler(ProblemException, self.problem_handler) 

21 self.add_exception_handler(Exception, self.common_error_handler) 

22 

23 @staticmethod 

24 def problem_handler(_request: StarletteRequest, exc: ProblemException): 

25 logger.exception(exc) 

26 

27 response = exc.to_problem() 

28 

29 return Response( 

30 content=response.body, 

31 status_code=response.status_code, 

32 media_type=response.mimetype, 

33 headers=response.headers, 

34 ) 

35 

36 @staticmethod 

37 def http_exception(_request: StarletteRequest, exc: HTTPException) -> Response: 

38 logger.exception(exc) 

39 

40 headers = exc.headers 

41 

42 connexion_response = problem( 

43 title=exc.detail, detail=exc.detail, status=exc.status_code, headers=headers 

44 ) 

45 

46 return Response( 

47 content=connexion_response.body, 

48 status_code=connexion_response.status_code, 

49 media_type=connexion_response.mimetype, 

50 headers=connexion_response.headers, 

51 ) 

52 

53 @staticmethod 

54 def common_error_handler(_request: StarletteRequest, exc: Exception) -> Response: 

55 logger.exception(exc) 

56 

57 response = InternalServerError().to_problem() 

58 

59 return Response( 

60 content=response.body, 

61 status_code=response.status_code, 

62 media_type=response.mimetype, 

63 headers=response.headers, 

64 ) 

65 

66 async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None: 

67 # Needs to be set so starlette router throws exceptions instead of returning error responses 

68 scope["app"] = "connexion" 

69 await super().__call__(scope, receive, send)