ข้ามไปยังเนื้อหา

Error Handling

ใน Express คุณเรียก res.status(404).json(...) หรือโยน error เข้า next(err) ส่วนใน FastAPI คุณ raise HTTPException ออกไปตรง ๆ เป็น Python exception ธรรมดาที่ FastAPI คอยดักจับแล้วแปลงเป็น HTTP response ให้ ผลคือ error path หน้าตาเหมือนโค้ด Python ปกติ

TypeScript
// Express — return error response
app.get('/items/:id', async (req, res) => {
const item = await db.findById(req.params.id);
if (!item) return res.status(404).json({ message: 'Item not found' });
res.json(item);
});
// NestJS — throw built-in exception
@Get(':id')
async findOne(@Param('id') id: string) {
const item = await this.itemsService.findOne(+id);
if (!item) throw new NotFoundException('Item not found');
return item;
}
Python
# FastAPI — raise HTTPException
from fastapi import FastAPI, HTTPException
app = FastAPI()
@app.get("/items/{item_id}")
async def get_item(item_id: int):
item = await db.find_by_id(item_id)
if not item:
raise HTTPException(status_code=404, detail="Item not found")
return item
# detail เป็น dict ได้สำหรับ structured errors
raise HTTPException(
status_code=422,
detail={"field": "price", "message": "must be positive"},
)

สำหรับ application-wide error handling เทียบเท่ากับ Express’s (err, req, res, next) error middleware FastAPI ใช้ @app.exception_handler

TypeScript
// Express global error middleware
app.use((err, req, res, next) => {
console.error(err.stack);
if (err.name === 'ValidationError') {
return res.status(400).json({ error: err.message });
}
res.status(500).json({ error: 'Internal Server Error' });
});
Python
# FastAPI custom exception handler
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
class ItemNotFoundError(Exception):
def __init__(self, item_id: int):
self.item_id = item_id
app = FastAPI()
@app.exception_handler(ItemNotFoundError)
async def item_not_found_handler(request: Request, exc: ItemNotFoundError):
return JSONResponse(
status_code=404,
content={"error": f"Item {exc.item_id} does not exist"},
)
@app.get("/items/{item_id}")
async def get_item(item_id: int):
raise ItemNotFoundError(item_id=item_id) # จับอัตโนมัติ

validation error handler ที่ FastAPI ให้มาในตัวจะคืน RequestValidationError ออกมา ซึ่งคุณ override เองได้ เพื่อให้รูปแบบตรงกับ error envelope ของ API

TypeScript
// Zod error shaping ใน Express
app.use((err, req, res, next) => {
if (err instanceof ZodError) {
return res.status(400).json({
errors: err.errors.map(e => ({ path: e.path, message: e.message })),
});
}
next(err);
});
Python
# Override FastAPI's default validation error handler
from fastapi import FastAPI, Request, status
from fastapi.exceptions import RequestValidationError
from fastapi.responses import JSONResponse
app = FastAPI()
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(
request: Request, exc: RequestValidationError
):
return JSONResponse(
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY,
content={
"errors": [
{"field": e["loc"][-1], "message": e["msg"]}
for e in exc.errors()
]
},
)

FastAPI HTTPException คือ Python exception ธรรมดา สำรวจวิธีที่ raise และ except ทำงานด้วย stdlib:

# Python exceptions — กลไกเดียวกับที่ FastAPI ใช้
class AppError(Exception):
\"\"\"Base class for application errors.\"\"\"
def __init__(self, message: str, status_code: int = 500):
self.message = message
self.status_code = status_code
super().__init__(message)
class NotFoundError(AppError):
def __init__(self, resource: str, resource_id: int):
super().__init__(f"{resource} {resource_id} not found", 404)
self.resource = resource
self.resource_id = resource_id
class ValidationError(AppError):
def __init__(self, field: str, message: str):
super().__init__(f"[{field}] {message}", 422)
def find_item(item_id: int):
if item_id <= 0:
raise ValidationError("item_id", "must be a positive integer")
if item_id > 100:
raise NotFoundError("Item", item_id)
return {"id": item_id, "name": "Widget"}
for test_id in [0, 42, 999]:
try:
result = find_item(test_id)
print(f"OK {test_id:4d} -> {result}")
except AppError as e:
print(f"ERR {test_id:4d} -> {e.status_code} {e.message}")
จะส่งคืน 404 response ใน FastAPI route handler ได้อย่างไร?
decorator ใดที่ใช้ลงทะเบียน global exception handler ใน FastAPI?
built-in FastAPI exception ใดที่ถูก raise เมื่อ Pydantic validation ล้มเหลวบน request?