Coverage for src/pyrf_api/exceptions.py: 100%

27 statements  

« prev     ^ index     » next       coverage.py v7.15.4, created at 2026-09-06 21:54 +0000

1"""Map lib exceptions to HTTP responses.""" 

2 

3import traceback 

4 

5from fastapi import Request 

6from fastapi.responses import JSONResponse 

7 

8 

9def _handle_value_error(_request: Request, exc: ValueError) -> JSONResponse: 

10 """Convert ValueError to HTTP 400 Bad Request.""" 

11 return JSONResponse(status_code=400, content={"detail": str(exc)}) 

12 

13 

14def _handle_assertion_error(_request: Request, exc: AssertionError) -> JSONResponse: 

15 """Convert AssertionError to HTTP 400 Bad Request.""" 

16 return JSONResponse(status_code=400, content={"detail": str(exc)}) 

17 

18 

19def _handle_type_error(_request: Request, exc: TypeError) -> JSONResponse: 

20 """Convert TypeError to HTTP 400 Bad Request.""" 

21 return JSONResponse(status_code=400, content={"detail": str(exc) or "Invalid input"}) 

22 

23 

24def _handle_zero_division(_request: Request, exc: ZeroDivisionError) -> JSONResponse: 

25 """Convert ZeroDivisionError to HTTP 400 Bad Request.""" 

26 return JSONResponse(status_code=400, content={"detail": str(exc)}) 

27 

28 

29def _handle_not_implemented(_request: Request, exc: NotImplementedError) -> JSONResponse: 

30 """Convert NotImplementedError to HTTP 501 Not Implemented.""" 

31 return JSONResponse(status_code=501, content={"detail": str(exc) or "Not implemented"}) 

32 

33 

34def _handle_frozen_instance(_request: Request, exc: BaseException) -> JSONResponse: 

35 """Convert attrs FrozenInstanceError to HTTP 400 Bad Request.""" 

36 return JSONResponse(status_code=400, content={"detail": "Invalid input"}) 

37 

38 

39def _handle_unhandled(_request: Request, exc: Exception) -> JSONResponse: 

40 """Convert unhandled exceptions to HTTP 500 Internal Server Error.""" 

41 traceback.print_exc() 

42 return JSONResponse(status_code=500, content={"detail": "Internal error"}) 

43 

44 

45def register_exception_handlers(app) -> None: 

46 """Register lib exception -> HTTP handlers on the FastAPI app.""" 

47 from attrs import exceptions as attrs_exceptions 

48 

49 app.add_exception_handler(ValueError, _handle_value_error) 

50 app.add_exception_handler(AssertionError, _handle_assertion_error) 

51 app.add_exception_handler(TypeError, _handle_type_error) 

52 app.add_exception_handler(ZeroDivisionError, _handle_zero_division) 

53 app.add_exception_handler(NotImplementedError, _handle_not_implemented) 

54 app.add_exception_handler(attrs_exceptions.FrozenInstanceError, _handle_frozen_instance) 

55 app.add_exception_handler(Exception, _handle_unhandled)