mirror of https://github.com/tiangolo/fastapi.git
Updated docs
This commit is contained in:
parent
f8b86bf714
commit
7115c1325e
|
|
@ -109,6 +109,37 @@ You could also use `from starlette.requests import Request` and `from starlette.
|
||||||
|
|
||||||
///
|
///
|
||||||
|
|
||||||
|
### Handle multiple exceptions or status codes
|
||||||
|
|
||||||
|
You can register the same handler for multiple exceptions or multiple status codes at once. Just pass a list or tuple of them to `@app.exception_handler(...)`.
|
||||||
|
|
||||||
|
This is useful when you want to group related errors together and respond with the same logic.
|
||||||
|
|
||||||
|
For example, if you want to treat 401 Unauthorized and 403 Forbidden as access-related issues:
|
||||||
|
|
||||||
|
{* ../../docs_src/handling_errors/tutorial007.py hl[15:20,33,37] *}
|
||||||
|
|
||||||
|
Raising an `HTTPException` with either a `401` or `403` status code will result in the same response detail:
|
||||||
|
|
||||||
|
```JSON
|
||||||
|
{"detail": "Access denied. Check your credentials or permissions."}
|
||||||
|
```
|
||||||
|
|
||||||
|
Or you can handle multiple exception classes like this:
|
||||||
|
|
||||||
|
{* ../../docs_src/handling_errors/tutorial008.py hl[10:12,15:17,20:25,32,38] *}
|
||||||
|
|
||||||
|
Here, if your request causes either a `FileTooLargeError` or an `UnsupportedFileTypeError`, the `custom_exception_handler` will be used to handle the exception and add a `hint` field to the response:
|
||||||
|
|
||||||
|
```JSON
|
||||||
|
{
|
||||||
|
"error": "The uploaded file is too large.",
|
||||||
|
"hint": "Need help? Contact support@example.com"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
This allows for simpler, more maintainable error handling when several conditions should result in the same kind of response.
|
||||||
|
|
||||||
## Override the default exception handlers
|
## Override the default exception handlers
|
||||||
|
|
||||||
**FastAPI** has some default exception handlers.
|
**FastAPI** has some default exception handlers.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
from typing import Union
|
||||||
|
|
||||||
|
from fastapi import FastAPI, HTTPException, Request
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
FAKE_DB = {
|
||||||
|
0: {"name": "Admin", "role": "ADMIN"},
|
||||||
|
1: {"name": "User 1", "role": "USER"},
|
||||||
|
2: {"name": "User 2", "role": "USER"},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@app.exception_handler([401, 403])
|
||||||
|
async def handle_auth_errors(request: Request, exc: Exception):
|
||||||
|
return JSONResponse(
|
||||||
|
status_code=exc.status_code if isinstance(exc, HTTPException) else 403,
|
||||||
|
content={"detail": "Access denied. Check your credentials or permissions."},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/secrets/")
|
||||||
|
async def get_secrets(auth_user_id: Union[int, None] = None):
|
||||||
|
# Get authenticated user info (not a production-ready code)
|
||||||
|
if auth_user_id is not None:
|
||||||
|
auth_user_info = FAKE_DB.get(auth_user_id)
|
||||||
|
else:
|
||||||
|
auth_user_info = None
|
||||||
|
|
||||||
|
# Return 401 status code if user not authenticated
|
||||||
|
if auth_user_info is None:
|
||||||
|
raise HTTPException(status_code=401) # Not authenticated
|
||||||
|
|
||||||
|
# Return 403 status code if user is not authorized to get secret information
|
||||||
|
if auth_user_info["role"] != "ADMIN":
|
||||||
|
raise HTTPException(status_code=403) # Not authorized
|
||||||
|
|
||||||
|
return {"data": "Secret information"}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
from fastapi import FastAPI, File, HTTPException, Request, UploadFile
|
||||||
|
from fastapi.responses import JSONResponse
|
||||||
|
|
||||||
|
MAX_FILE_SIZE_MB = 5
|
||||||
|
ALLOWED_TYPES = {"application/pdf", "image/jpeg"}
|
||||||
|
|
||||||
|
app = FastAPI()
|
||||||
|
|
||||||
|
|
||||||
|
class FileTooLargeError(HTTPException):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(status_code=413, detail="The uploaded file is too large.")
|
||||||
|
|
||||||
|
|
||||||
|
class UnsupportedFileTypeError(HTTPException):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__(status_code=415, detail="Unsupported file type")
|
||||||
|
|
||||||
|
|
||||||
|
@app.exception_handler((FileTooLargeError, UnsupportedFileTypeError))
|
||||||
|
def custom_exception_handler(request: Request, exc: HTTPException):
|
||||||
|
return JSONResponse(
|
||||||
|
status_code=exc.status_code,
|
||||||
|
content={"error": exc.detail, "hint": "Need help? Contact support@example.com"},
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@app.post("/upload/")
|
||||||
|
async def upload_file(file: UploadFile = File(...)):
|
||||||
|
# Validate file type
|
||||||
|
if file.content_type not in ALLOWED_TYPES:
|
||||||
|
raise UnsupportedFileTypeError()
|
||||||
|
|
||||||
|
# Validate file size (read contents to check size in memory)
|
||||||
|
contents = await file.read()
|
||||||
|
size_mb = len(contents) / (1024 * 1024)
|
||||||
|
if size_mb > MAX_FILE_SIZE_MB:
|
||||||
|
raise FileTooLargeError()
|
||||||
|
|
||||||
|
return {"filename": file.filename, "message": "File uploaded successfully!"}
|
||||||
Loading…
Reference in New Issue