YouTip LogoYouTip

Fastapi Error Handling

In API development, error information needs to be returned to clients. FastAPI provides `HTTPException` for throwing HTTP errors, and also supports custom exception handlers for more complex error scenarios.\n\n* * *\n\n## Using HTTPException\n\nWhen an error response needs to be returned, throw `HTTPException`:\n\n## Example\n\n```python\nfrom fastapi import FastAPI, HTTPException\n\napp = FastAPI()\n\nitems = {"foo": "The Foo Wrestlers", "bar": "The Bar Fighters"}\n\n@app.get("/items/{item_id}")\nasync def read_item(item_id: str):\n if item_id not in items:\n # Throw 404 error when resource does not exist\n raise HTTPException(status_code=404, detail="Item not found")\n return {"item": items}\n\nWhen accessing **http://127.0.0.1:8000/items/42**, it returns:\n\n```json\n{ "detail": "Item not found"}\n\nThe HTTP status code is `404`.\n\n> Note that `raise` is used here instead of `return`. `HTTPException` is an exception; after being thrown, FastAPI catches it and returns the corresponding HTTP error response. This is consistent with Python's exception handling mechanism.\n\n* * *\n\n## HTTPException Parameters\n\n| Parameter | Type | Description |\n| --- | --- | --- |\n| `status_code` | `int` | HTTP status code (required) |\n| `detail` | `Any` | Error details, can be string, dict, list, etc. |\n| `headers` | `dict | None` | Additional response headers (optional) |\n\n* * *\n\n## Custom Error Details\n\nThe `detail` parameter can be any type, not limited to strings:\n\n## Example\n\n```python\nfrom fastapi import FastAPI, HTTPException\n\napp = FastAPI()\n\n@app.get("/items/{item_id}")\nasync def read_item(item_id: str):\n if item_id == "invalid":\n # detail can be a dict containing more error information\n raise HTTPException(\n status_code=400,\n detail={\n "error_code": "INVALID_ID",\n "message": "Invalid product ID format",\n "hint": "Please use an alphanumeric ID"\n }\n )\n return {"item_id": item_id}\n\n* * *\n\n## Adding Custom Response Headers\n\nIn certain scenarios, custom response headers need to be added to error responses:\n\n## Example\n\n```python\nfrom fastapi import FastAPI, HTTPException\n\napp = FastAPI()\n\n@app.get("/items-header/{item_id}")\nasync def read_item_header(item_id: str):\n if item_id == "invalid":\n raise HTTPException(\n status_code=404,\n detail="Item not found",\n headers={"X-Error": "There goes my error"}, # custom response header\n )\n return {"item": item_id}\n\n> In scenarios where client request rate needs to be limited (rate limiting), the `Retry-After` header can be added to error response headers to tell the client when to retry.\n\n* * *\n\n## Custom Exception Handlers\n\nYou can register handlers for custom exceptions or built-in exceptions to uniformly handle error response formats:\n\n## Example\n\n```python\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import JSONResponse\n\n# Custom exception class\nclass UnicornException(Exception):\n def __init__(self, name: str):\n self.name = name\n\napp = FastAPI()\n\n# Register exception handler\n@app.exception_handler(UnicornException)\nasync def unicorn_exception_handler(request: Request, exc: UnicornException):\n # Return custom formatted error response\n return JSONResponse(\n status_code=418,\n content={"message": f"Oops! {exc.name} did something wrong"},\n )\n\n@app.get("/unicorns/{name}")\nasync def read_unicorn(name: str):\n if name == "yolo":\n # Throw custom exception\n raise UnicornException(name=name)\n return {"unicorn_name": name}\n\n* * *\n\n## Overriding Default Exception Handlers\n\nFastAPI has default exception handlers that you can override to customize error response formats:\n\n## Example\n\n```python\nfrom fastapi import FastAPI, Request\nfrom fastapi.responses import JSONResponse\nfrom fastapi.exceptions import RequestValidationError\nfrom starlette.exceptions import HTTPException as StarletteHTTPException\n\napp = FastAPI()\n\n# Override HTTP exception handler\n@app.exception_handler(StarletteHTTPException)\nasync def http_exception_handler(request: Request, exc: StarletteHTTPException):\n return JSONResponse(\n status_code=exc.status_code,\n content={"error": f"HTTP error: {exc.detail}"},\n )\n\n# Override request validation exception handler\n@app.exception_handler(RequestValidationError)\nasync def validation_exception_handler(request: Request, exc: RequestValidationError):\n return JSONResponse(\n status_code=422,\n content={"error": "Data validation failed", "details": exc.errors()},\n )\n\n> `RequestValidationError` is the exception thrown by FastAPI when request data validation fails. Overriding its handler allows customizing the response format for validation errors.\n\n* * *\n\n## Redirects\n\nUse `RedirectResponse` to implement redirects:\n\n## Example\n\n```python\nfrom fastapi import FastAPI\nfrom fastapi.responses import RedirectResponse\n\napp = FastAPI()\n\n@app.get("/items/")\nasync def read_items():\n return {"items": ["foo", "bar"]}\n\n@app.get("/redirect")\nasync def redirect():\n # Redirect to /items/\n return RedirectResponse(url="/items/")\n\n* * *\n\n## Custom Response Headers and Status Codes\n\nUse `JSONResponse` to customize response headers and status codes:\n\n## Example\n\n```python\nfrom fastapi import FastAPI\nfrom fastapi.responses import JSONResponse\n\napp = FastAPI()\n\n@app.get("/items/{item_id}")\nasync def read_item(item_id: int):\n content = {"item_id": item_id}\n headers = {"X-Custom-Header": "custom-header-value"}\n return JSONResponse(content=content, headers=headers)\n\n* * *\n\n## Summary\n\n* Use `raise HTTPException` to return HTTP error responses\n* The `detail` parameter can be any type (string, dict, list, etc.)\n* Use `@app.exception_handler` to register custom exception handlers\n* Default FastAPI exception handlers can be overridden to unify error formats\n* Use `RedirectResponse` to implement redirects
← Fastapi CorsFastapi File Upload β†’