Global Exception Handler
Exit

Global Exception Handler

Add a catch-all handler that returns consistent JSON for any unhandled error

💻

Writing code and entering commands is only available on desktop. Open this page on a larger screen to complete this chapter.

The problem with unhandled errors

Your API handles expected errors like "expense not found" with HTTPException. But what about unexpected errors — a bug in your code, a corrupted file, or an import that fails at runtime?

Without a handler, FastAPI returns a raw 500 error. The response format varies, and in some cases the response body contains a Python traceback — exposing internal code paths to the client. This is both unhelpful for the client and a security risk.

A consistent error response

A global exception handler catches any unhandled exception and replaces it with a consistent JSON response:

{"detail": "Internal server error"}

The client always gets the same shape, regardless of what went wrong internally. The real error details go to the server logs, where developers can see them without exposing them to users.

How it works

FastAPI's @app.exception_handler(Exception) decorator registers a function that catches any exception not already handled by a more specific handler. Your HTTPException handlers still work normally — this handler only catches what falls through.

Instructions

Add a global exception handler.

  1. Add two imports at the top of the file: traceback and JSONResponse from fastapi.responses.
  2. After the middleware and before the first endpoint, add the @app.exception_handler(Exception) decorator.
  3. Define an async function called global_exception_handler that takes request and exc as parameters.
  4. Inside the function, call traceback.print_exc() — this logs the full error traceback to the console.
  5. Return JSONResponse(status_code=500, content={"detail": "Internal server error"}).