Error handling¶
Django-Bolt provides a structured exception hierarchy for HTTP errors and automatic error response formatting.
Exception classes¶
HTTPException¶
The base class for all HTTP errors:
from django_bolt.exceptions import HTTPException
raise HTTPException(status_code=400, detail="Bad request")
Parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
status_code |
int |
required | HTTP status code |
detail |
str |
HTTP phrase | Error message |
headers |
dict |
{} |
Response headers |
extra |
dict |
None |
Additional error data |
Specialized exceptions¶
Django-Bolt provides pre-configured exceptions for common status codes:
from django_bolt.exceptions import (
# 4xx Client Errors
BadRequest, # 400
Unauthorized, # 401
Forbidden, # 403
NotFound, # 404
MethodNotAllowed, # 405
NotAcceptable, # 406
Conflict, # 409
Gone, # 410
UnprocessableEntity, # 422
TooManyRequests, # 429
# 5xx Server Errors
InternalServerError, # 500
BadGateway, # 502
ServiceUnavailable, # 503
GatewayTimeout, # 504
)
Usage:
@api.get("/users/{user_id}")
async def get_user(user_id: int):
user = await User.objects.filter(id=user_id).afirst()
if not user:
raise NotFound(detail="User not found")
return {"id": user.id, "username": user.username}
Custom headers¶
Add headers to error responses:
Extra data¶
Include additional information in the error response:
raise BadRequest(
detail="Invalid input",
extra={
"field": "email",
"value": "invalid@",
"reason": "Invalid email format"
}
)
Response:
{
"detail": "Invalid input",
"extra": {
"field": "email",
"value": "invalid@",
"reason": "Invalid email format"
}
}
Validation errors¶
RequestValidationError¶
Raised when request validation fails:
from django_bolt.exceptions import RequestValidationError
errors = [
{
"loc": ["body", "email"],
"msg": "Invalid email format",
"type": "value_error"
},
{
"loc": ["body", "age"],
"msg": "Must be positive",
"type": "value_error"
}
]
raise RequestValidationError(errors)
Response (422 Unprocessable Entity):
{
"detail": [
{
"loc": ["body", "email"],
"msg": "Invalid email format",
"type": "value_error"
},
{
"loc": ["body", "age"],
"msg": "Must be positive",
"type": "value_error"
}
]
}
ResponseValidationError¶
Raised when response validation fails (returns 500):
from django_bolt.exceptions import ResponseValidationError
errors = [
{
"loc": ["response", "id"],
"msg": "Field required",
"type": "missing"
}
]
raise ResponseValidationError(errors)
Response validation errors indicate a server bug, so they return 500 Internal Server Error.
Error handlers¶
Django-Bolt provides built-in error handlers:
http_exception_handler¶
Handles HTTPException and its subclasses:
from django_bolt.error_handlers import http_exception_handler
exc = NotFound(detail="User not found")
status, headers, body = http_exception_handler(exc)
# status: 404
# body: b'{"detail": "User not found"}'
request_validation_error_handler¶
Handles RequestValidationError:
from django_bolt.error_handlers import request_validation_error_handler
errors = [{"loc": ["body"], "msg": "Invalid", "type": "value_error"}]
exc = RequestValidationError(errors)
status, headers, body = request_validation_error_handler(exc)
# status: 422
generic_exception_handler¶
Handles unexpected exceptions:
from django_bolt.error_handlers import generic_exception_handler
exc = ValueError("Something went wrong")
# Production mode - hide details
status, headers, body = generic_exception_handler(exc, debug=False)
# body: b'{"detail": "Internal Server Error"}'
# Debug mode - show Django error page
status, headers, body = generic_exception_handler(exc, debug=True)
# Returns HTML error page with traceback
handle_exception¶
The main entry point that routes to appropriate handlers:
from django_bolt.error_handlers import handle_exception
# Automatically detects exception type
status, headers, body = handle_exception(some_exception)
Debug mode¶
In debug mode (DEBUG=True in Django settings), unhandled exceptions return Django's HTML error page with full traceback:
# debug=True: Full HTML traceback page
status, headers, body = handle_exception(exc, debug=True)
# content-type: text/html
# debug=False: JSON error response
status, headers, body = handle_exception(exc, debug=False)
# content-type: application/json
The debug parameter defaults to Django's DEBUG setting.
msgspec validation errors¶
Django-Bolt converts msgspec.ValidationError to the standard error format:
from django_bolt.error_handlers import msgspec_validation_error_to_dict
try:
msgspec.json.decode(b'{"age": "invalid"}', type=MyStruct)
except msgspec.ValidationError as e:
errors = msgspec_validation_error_to_dict(e)
# [{"loc": [...], "msg": "...", "type": "..."}]
Error response format¶
All errors follow a consistent format:
For validation errors:
Example: Custom error handling¶
from django_bolt import BoltAPI
from django_bolt.exceptions import HTTPException, NotFound, BadRequest
api = BoltAPI()
@api.get("/users/{user_id}")
async def get_user(user_id: int):
if user_id < 1:
raise BadRequest(
detail="Invalid user ID",
extra={"user_id": user_id, "reason": "Must be positive"}
)
user = await User.objects.filter(id=user_id).afirst()
if not user:
raise NotFound(detail=f"User {user_id} not found")
return {"id": user.id, "username": user.username}
@api.post("/orders")
async def create_order(data: OrderCreate):
try:
order = await Order.objects.acreate(**data.__dict__)
return {"id": order.id}
except IntegrityError:
raise BadRequest(
detail="Order creation failed",
extra={"reason": "Duplicate order reference"}
)
Chaining exceptions¶
Preserve the original exception context:
The original traceback is preserved for debugging.
Exception reference¶
Client errors (4xx)¶
| Exception | Status Code | Default Message |
|---|---|---|
BadRequest |
400 | Bad Request |
Unauthorized |
401 | Unauthorized |
Forbidden |
403 | Forbidden |
NotFound |
404 | Not Found |
MethodNotAllowed |
405 | Method Not Allowed |
NotAcceptable |
406 | Not Acceptable |
Conflict |
409 | Conflict |
Gone |
410 | Gone |
UnprocessableEntity |
422 | Unprocessable Entity |
TooManyRequests |
429 | Too Many Requests |
Server errors (5xx)¶
| Exception | Status Code | Default Message |
|---|---|---|
InternalServerError |
500 | Internal Server Error |
BadGateway |
502 | Bad Gateway |
ServiceUnavailable |
503 | Service Unavailable |
GatewayTimeout |
504 | Gateway Timeout |