示范二
import traceback
from typing import Optional, Any, Annotated
from fastapi import FastAPI, Depends, Header, HTTPException
from fastapi.responses import JSONResponse
from fastapi.exceptions import RequestValidationError
from pydantic import BaseModel
# ====== 模拟 Redis(你换成真实的 r.hget 即可)======
FAKE_DB = {
"1001": "abc123"
}
# ====== 统一返回函数 ======
def resp(code=0, msg="success", data=None, http_status=200):
return JSONResponse(
status_code=http_status,
content={
"code": code,
"msg": msg,
"data": data
}
)
# ====== 自定义业务异常 ======
class BizException(Exception):
def __init__(self, code: int, msg: str, http_status: int = 400):
self.code = code
self.msg = msg
self.http_status = http_status
# ====== 全局鉴权 ======
async def verify_auth(
bid: Annotated[Optional[str], Header()] = None,
token: Annotated[Optional[str], Header()] = None
):
if not bid or not token:
raise BizException(1001, "Missing auth", 401)
token_redis = FAKE_DB.get(bid)
if not token_redis:
raise BizException(1002, "Token not found", 401)
if token != token_redis:
raise BizException(1003, "Invalid token", 403)
# ====== 创建 app(带全局依赖)======
app = FastAPI(dependencies=[Depends(verify_auth)])
# ====== 全局异常处理 ======
# 1️⃣ 业务异常
@app.exception_handler(BizException)
async def biz_exception_handler(request, exc: BizException):
return resp(
code=exc.code,
msg=exc.msg,
http_status=exc.http_status
)
# 2️⃣ 参数校验异常
@app.exception_handler(RequestValidationError)
async def validation_exception_handler(request, exc: RequestValidationError):
return resp(
code=1100,
msg="Invalid parameters",
data=exc.errors(), # 生产环境可以去掉
http_status=400
)
# 3️⃣ HTTPException
@app.exception_handler(HTTPException)
async def http_exception_handler(request, exc: HTTPException):
return resp(
code=1000,
msg=str(exc.detail),
http_status=exc.status_code
)
# 4️⃣ 全局兜底异常(500)
@app.exception_handler(Exception)
async def global_exception_handler(request, exc: Exception):
print("🔥 服务器异常:")
print(traceback.format_exc())
return resp(
code=1000,
msg="Internal server error",
http_status=500
)
# ====== 数据模型 ======
class Item(BaseModel):
name: str
price: float
is_offer: Optional[bool] = None
# ====== 接口示例 ======
@app.get("/ok")
async def ok():
return resp(data={"msg": "正常返回"})
@app.get("/biz_error")
async def biz_error():
raise BizException(2001, "业务逻辑错误", 400)
@app.get("/http_error")
async def http_error():
raise HTTPException(status_code=404, detail="Not found")
@app.get("/server_error")
async def server_error():
x = 1 / 0 # 故意报错
return resp()
@app.post("/item")
async def create_item(item: Item):
return resp(data=item.dict())