fastapi: 多个子应用时判断全局异常的处理形式

📅 2026/7/23 18:56:14 👁️ 阅读次数 📝 编程学习
fastapi: 多个子应用时判断全局异常的处理形式

一,代码

场景:

fastapi项目下面有两个子应用,一个是api: 接口站,另一个是admin:管理后台,
api接口站,处理异常后返回json,
admin.管理后台,有传统的页面请求也有ajax方式访问,
要求非ajax时,返回到一个错误信息页面,
ajax访问时,当然是返回json

代码:

# 返回异常信息,根据子应用和是否ajax分别进行处理,管理后非ajax请求,跳到错误页面
def response_exception(request: Request,err_data):path = request.url.path# --- 状况 A:如果是 API 子应用的请求,一律返回 JSON ---if path.startswith("/api"):return JSONResponse(status_code=err_data['status_code'],content={"data": {}, "msg": err_data['detail'], "code": err_data['status_code']})# --- 状况 B:如果是 Admin 子应用的请求,需要分情况讨论 ---elif path.startswith("/admin"):accept_header = request.headers.get("accept", "")requested_with = request.headers.get("x-requested-with", "")# 判断是否为 Ajax 请求:# 1. 检查 X-Requested-With 是否为 XMLHttpRequest (传统 Ajax)# 2. 或者检查 Accept 头是否更倾向于接收 JSON (现代 fetch/axios 请求)is_ajax = (requested_with.lower() == "xmlhttprequest" or("application/json" in accept_header and "text/html" not in accept_header))if is_ajax:# 管理后台的 Ajax 请求出错 -> 返回 JSON 方便前端弹窗提示(如 ElementUI/AntDesign)return JSONResponse(status_code=err_data['status_code'],content={"data": {}, "msg": err_data['detail'], "code": err_data['status_code']})else:# 传统的浏览器地址栏直接访问或表单提交出错 -> 渲染精美的错误 HTML 页面# 传入 request 和 错误信息 供模板渲染return templates.TemplateResponse(name="error/error.html",context={"request": request, "status_code": err_data['status_code'], "detail": err_data['detail']},status_code=err_data['status_code'],request=request,)

error.html:

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>出错了 - {{ status_code }}</title>
</head>
<body><div style="text-align: center; margin-top: 100px;"><h1>抱歉,系统响应异常 ({{ status_code }})</h1><p style="color: red;">错误原因:{{ detail }}</p><a href="/admin/dashboard">返回管理后台首页</a></div>
</body>
</html>

 

 

二,测试效果 :

页面

image

json

image