Error Handling: HTTP Exceptions and Responses

Error Handling: HTTP Exceptions and Responses

Communicate failure clearly. Learn how to use HTTPException to return standard error messages and status codes to your clients.

Error Handling: HTTP Exceptions and Responses

In a perfect world, your API never fails. In the real world, database connections drop, users forget their passwords, and resources are deleted.

A professional API is defined by how it handles failure. In FastAPI, we communicate these failures using the HTTPException.


1. The HTTPException Class

FastAPI provides a dedicated HTTPException class that you can raise at any point in your code (including inside dependencies).

from fastapi import HTTPException

@app.get("/items/{item_id}")
async def read_item(item_id: str):
    if item_id not in items_db:
        raise HTTPException(
            status_code=404, 
            detail="Item not found",
            headers={"X-Error": "Custom Error Info"}
        )
    return {"item": items_db[item_id]}

2. Why "Raise" and not "Return"?

Unlike other frameworks where you might return {"error": "msg"}, 404, in FastAPI we use raise.

The Benefits of raise:

  • Instant Stop: As soon as you raise the exception, the function stops. You don't need to worry about the rest of the logic accidentally running.
  • Dependency Support: If an error happens deep inside a dependency chain, you can raise the exception there, and it will propagate correctly to the user.
  • Clean Logic: It keeps your "Happy Path" (success logic) separate from your error handling.

3. Standard JSON Error Format

By default, FastAPI returns a standardized JSON structure for all errors. This is extremely helpful for frontend developers because they can write a single piece of code to handle all API failures.

{
  "detail": "Item not found"
}

4. Customizing Error Metadata

Sometimes detail isn't enough. You might want to send back a specific error code or a hint to the user.

raise HTTPException(
    status_code=403,
    detail={
        "error_code": "INSUFFICIENT_FUNDS",
        "message": "You need $5 more to complete this purchase",
        "link": "https://shshell.com/top-up"
    }
)

Visualizing Error Propagation

graph TD
    A["Endpoint Start"] --> B["Dependency Check"]
    B -- "Fail" --> C["Raise HTTPException"]
    C --> D["FastAPI Error Handler"]
    D --> E["404 Response (Client)"]
    
    B -- "Pass" --> F["Business Logic"]
    F -- "Item missing?" --> C
    F -- "Found" --> G["200 Response (Client)"]

Summary

  • HTTPException: Use it for all "expected" errors (404, 401, 403).
  • Status Codes: Be precise. Don't send a 400 if you mean 404.
  • Detail: You can pass a string or a full dictionary to the detail parameter.

In the next lesson, we’ll see how to handle "unexpected" errors using Custom Exception Handlers.


Exercise: The Access Denied

You are building an API for a Secret Library. If a user tries to access a book they don't have permission for, what status code should you use? Write the raise statement that includes the message "Access denied. Level 5 clearance required."

Subscribe to our newsletter

Get the latest posts delivered right to your inbox.

Subscribe on LinkedIn