FastAPI作为高性能的Python Web框架,提供了灵活的异常处理机制,通过全局异常捕获可以统一处理请求过程中出现的各类错误,避免每个接口都单独编写错误处理代码,让接口返回格式更统一,也便于后续的错误排查和功能迭代。

FastAPI内置异常处理器基础用法
FastAPI自带了@app.exception_handler()装饰器,可以用来注册全局的异常处理器,处理指定的异常类型。比如我们可以捕获内置的HTTPException,统一返回自定义的响应格式。
from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponse
app = FastAPI()
# 捕获HTTPException的全局处理器
@app.exception_handler(HTTPException)
async def http_exception_handler(request, exc):
return JSONResponse(
status_code=exc.status_code,
content={
"code": exc.status_code,
"message": exc.detail,
"data": None
}
)
@app.get("/items/{item_id}")
async def get_item(item_id: int):
if item_id < 1:
raise HTTPException(status_code=400, detail="item_id必须大于0")
return {"item_id": item_id}
自定义异常类的全局捕获
实际开发中我们经常需要定义业务相关的自定义异常,同样可以通过全局异常处理器统一捕获。首先需要定义自定义异常类,然后注册对应的处理器即可。
from fastapi import FastAPI
from fastapi.responses import JSONResponse
app = FastAPI()
# 自定义业务异常类
class BusinessException(Exception):
def __init__(self, code: int, message: str):
self.code = code
self.message = message
super().__init__(self.message)
# 捕获自定义业务异常的全局处理器
@app.exception_handler(BusinessException)
async def business_exception_handler(request, exc):
return JSONResponse(
status_code=200, # 业务异常通常返回200,通过code区分错误类型
content={
"code": exc.code,
"message": exc.message,
"data": None
}
)
@app.get("/users/{user_id}")
async def get_user(user_id: int):
if user_id == 999:
raise BusinessException(code=10001, message="用户不存在")
return {"user_id": user_id}
捕获所有未处理异常的兜底方案
为了处理所有未被特定处理器捕获的异常,我们可以注册一个捕获Exception基类的全局处理器,作为异常处理的兜底逻辑,避免接口返回框架默认的错误堆栈信息。
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
app = FastAPI()
# 兜底捕获所有未处理异常的全局处理器
@app.exception_handler(Exception)
async def all_exception_handler(request: Request, exc: Exception):
# 实际生产中可以添加日志记录异常信息
return JSONResponse(
status_code=500,
content={
"code": 500,
"message": "服务器内部错误,请联系管理员",
"data": None
}
)
@app.get("/test-error")
async def test_error():
# 触发未捕获的异常
result = 1 / 0
return {"result": result}
结合中间件的异常处理补充
除了异常处理器,我们还可以结合FastAPI的中间件处理请求过程中的异常,不过中间件更适合处理请求级别的前后置逻辑,全局异常捕获还是优先使用异常处理器的方式,两者可以配合使用。
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
app = FastAPI()
@app.middleware("http")
async def exception_middleware(request: Request, call_next):
try:
response = await call_next(request)
return response
except Exception as exc:
# 中间件中的异常捕获可以作为补充,不过优先级低于专门的异常处理器
return JSONResponse(
status_code=500,
content={
"code": 500,
"message": "中间件捕获到未处理异常",
"data": None
}
)
全局异常处理的注意事项
在配置全局异常捕获时,需要注意处理器的注册顺序,FastAPI会按照注册顺序匹配异常处理器,更具体的异常处理器应该先注册,比如先注册BusinessException的处理器,再注册Exception的处理器,否则自定义异常可能会被兜底的Exception处理器捕获。
另外,生产环境中全局异常处理器内部建议添加异常日志记录,方便后续排查问题,同时不要将详细的错误堆栈信息返回给客户端,避免暴露服务器敏感信息。
| 异常类型 | 适用场景 | 返回状态码建议 |
|---|---|---|
| HTTPException | 请求参数错误、权限不足等客户端错误 | 对应HTTP状态码(如400、401) |
| 自定义业务异常 | 业务逻辑校验失败等业务错误 | 200(通过响应体code区分) |
| 未捕获的Exception | 服务器内部未知错误 | 500 |