Skip to content

Handling Errors

Raise an HTTPException to return an error response:

from justapi import JustAPIApp, HTTPException
app = JustAPIApp()
@app.get("/items/{item_id}")
def get_item(item_id: int):
if item_id == 0:
raise HTTPException(status_code=404, detail="Item not found")
return {"item_id": item_id}
@app.get("/items/{item_id}")
def get_item(item_id: int):
if item_id == 0:
raise HTTPException(
status_code=404,
detail="Item not found",
headers={"X-Error": "item-not-found"},
)
return {"item_id": item_id}

When request data doesn’t match the schema, JustAPI returns a 422 error automatically:

{
"detail": [
{
"type": "int_parsing",
"loc": ["path", "item_id"],
"msg": "Input should be a valid integer",
"input": "foo"
}
]
}

The detail array contains every validation error with:

  • type — error category
  • loc — where the error occurred (["path", "body", "query", "header"])
  • msg — human-readable message
  • input — the value that was rejected

Customize the validation error response:

from justapi import JustAPIApp
from starlette.requests import Request
from starlette.responses import JSONResponse
app = JustAPIApp()
@app.exception_handler(RequestValidationError)
async def validation_error_handler(request: Request, exc):
return JSONResponse(
status_code=422,
content={
"error": "validation_error",
"message": "Invalid request data",
"details": exc.errors(),
},
)

Change the default HTTP error format:

from fastapi.exception_handlers import http_exception_handler
@app.exception_handler(HTTPException)
async def custom_http_exception(request, exc):
return JSONResponse(
status_code=exc.status_code,
content={
"error": "http_error",
"message": exc.detail,
"status_code": exc.status_code,
},
)

Create your own exception and handler:

class InsufficientFundsError(Exception):
def __init__(self, balance: float, amount: float):
self.balance = balance
self.amount = amount
@app.exception_handler(InsufficientFundsError)
async def insufficient_funds_handler(request, exc):
return JSONResponse(
status_code=402,
content={
"error": "insufficient_funds",
"message": f"Need {exc.amount}, have {exc.balance}",
},
)
@app.post("/purchase")
def purchase(amount: float):
balance = 100.0
if amount > balance:
raise InsufficientFundsError(balance, amount)
return {"status": "ok"}
app = JustAPIApp(debug=True)

Debug mode returns detailed tracebacks in responses.

Never use debug=True in production. It exposes internal details.

Status Code Meaning Cause
404 Not Found Route doesn’t exist
405 Method Not Allowed Wrong HTTP method
422 Validation Error Request data doesn’t match schema
401 Unauthorized Missing or invalid auth
403 Forbidden Authenticated but not authorized