Skip to content

Commit

Permalink
format internal server errors as standard exception response format. …
Browse files Browse the repository at this point in the history
…fix internal server error tracebacks
  • Loading branch information
frostyfan109 committed Dec 18, 2024
1 parent 3eda9bc commit 4afaa31
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 5 deletions.
6 changes: 4 additions & 2 deletions app/core/middleware/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ async def dispatch(self, request: Request, call_next: Callable):
request_log["error_code"] = resp_body["error_code"]
request_log["message"] = resp_body["message"]
self._logger.error(request_log)
# self._logger.error(resp_body["stack"])
elif type(resp_body) is str:
# If the resp_body is of type str because the above json.loads() failed,
# don't add the fields above, just use the whole resp_body
Expand Down Expand Up @@ -131,12 +130,15 @@ async def _execute_request(
response.headers["X-API-Request-ID"] = request_id
return response
except Exception as e:
# If we hit an exception here, it is a non-HTTP error, i.e., it is an internal server error.
exception_log = {
"path": request.url.path,
"method": request.method,
"reason": e
}
self._logger.exception(exception_log)
self._logger.error(exception_log)
# Starlette will log the internal traceback for us automatically.
raise e

def _get_endpoints_to_not_log_req_body(self) -> list[str]:
return [
Expand Down
16 changes: 13 additions & 3 deletions app/main.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from logging.handlers import RotatingFileHandler
import sys
import logging
from logging.handlers import RotatingFileHandler
from typing import List
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
Expand All @@ -14,7 +15,6 @@
from app.core.middleware import AuthenticationMiddleware, AuthBackend, LogMiddleware
from app.core.exceptions import CustomException

import logging

formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s")

Expand Down Expand Up @@ -53,9 +53,19 @@ def init_routers(app: FastAPI):
app.include_router(api_router, prefix=settings.API_V1_STR)

def init_listeners(app: FastAPI):
# Errors go to the most specialized handler, so this will only pick up
# non CustomException and non FastAPI/starlette errors (internal server errors)
@app.exception_handler(Exception)
async def base_exception_handler(request: Request, exc: Exception):
content = { "error_code": 500, "message": "Internal server error" }
return JSONResponse(
status_code=500,
content=content
)
@app.exception_handler(CustomException)
async def custom_exception_handler(request: Request, exc: CustomException):
uvicorn_logger.error(exc.stack)
# Only log regular CustomException errors under debug
uvicorn_logger.debug(exc.stack)
content = { "error_code": exc.error_code, "message": exc.message }
if settings.DEV_PHASE == DevPhase.DEV:
content["stack"] = exc.stack
Expand Down

0 comments on commit 4afaa31

Please sign in to comment.