Skip to content

Commit ef3b02a

Browse files
committed
feat: improve exception handlers
1 parent cbc0f91 commit ef3b02a

File tree

1 file changed

+44
-12
lines changed

1 file changed

+44
-12
lines changed

api/chatbot/exception_handlers.py

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,64 @@
11
import logging
22

33
from fastapi import FastAPI, status
4-
from fastapi.encoders import jsonable_encoder
54
from fastapi.requests import Request
65
from fastapi.responses import JSONResponse
7-
8-
from sqlalchemy.exc import NoResultFound
9-
6+
from sqlalchemy.exc import IntegrityError, NoResultFound
107

118
logger = logging.getLogger(__name__)
129

1310

1411
def register_exception_handlers(app: FastAPI):
15-
app.add_exception_handler(NoResultFound, not_found_error_handler)
16-
app.add_exception_handler(Exception, exception_handler)
12+
app.add_exception_handler(NoResultFound, handle_no_result_found)
13+
app.add_exception_handler(IntegrityError, handle_integrity_error)
14+
app.add_exception_handler(ValueError, handle_value_error)
15+
app.add_exception_handler(PermissionError, handle_permission_error)
16+
app.add_exception_handler(ConnectionError, handle_connection_error)
17+
app.add_exception_handler(Exception, handle_generic_exception)
1718

1819

19-
def not_found_error_handler(request: Request, exc: NoResultFound):
20+
def handle_no_result_found(request: Request, exc: NoResultFound):
2021
return JSONResponse(
2122
status_code=status.HTTP_404_NOT_FOUND,
22-
content=jsonable_encoder({"detail": str(exc)}),
23+
content={"message": "Resource not found", "detail": str(exc)},
24+
)
25+
26+
27+
def handle_integrity_error(request: Request, exc: IntegrityError):
28+
return JSONResponse(
29+
status_code=status.HTTP_409_CONFLICT,
30+
content={"message": "Resource already exists", "detail": str(exc)},
31+
)
32+
33+
34+
def handle_value_error(request: Request, exc: ValueError):
35+
logger.exception("Unhandled ValueError: %s", exc)
36+
return JSONResponse(
37+
status_code=status.HTTP_400_BAD_REQUEST,
38+
content={"message": "Invalid input", "detail": str(exc)},
39+
)
40+
41+
42+
def handle_permission_error(request: Request, exc: PermissionError):
43+
logger.exception("Unhandled PermissionError: %s", exc)
44+
return JSONResponse(
45+
status_code=status.HTTP_403_FORBIDDEN,
46+
content={"message": "Permission denied", "detail": str(exc)},
47+
)
48+
49+
50+
def handle_connection_error(request: Request, exc: ConnectionError):
51+
logger.exception("Unhandled ConnectionError: %s", exc)
52+
return JSONResponse(
53+
status_code=status.HTTP_503_SERVICE_UNAVAILABLE,
54+
content={"message": "Service unavailable", "detail": str(exc)},
2355
)
2456

2557

26-
def exception_handler(request: Request, exc: Exception):
27-
"""Global exception handler."""
28-
logger.exception("Unhandled error during request %s", request)
58+
def handle_generic_exception(request: Request, exc: Exception):
59+
logger.exception("Unhandled exception: %s", exc)
2960
return JSONResponse(
3061
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
31-
content={"detail": "server error"},
62+
# Do not expose error details
63+
content={"message": "Server error"},
3264
)

0 commit comments

Comments
 (0)