最稳妥可控的全局异常处理方式是使用中间件的process_exception方法,它能捕获所有视图异常(含自定义业务异常),兼容Django与DRF混用场景,且不侵入DRF异常链;需注意显式返回JsonResponse、路径过滤、注册顺序及异步适配等关键点。

直接用中间件 + process_exception 是最稳妥、可控的方式,尤其当你同时跑普通 Django 视图和 DRF API 时。别试图覆盖 handle_uncaught_exception 或改 BaseHandler,那些路径不可靠、调试困难、还容易被其他中间件干扰。
用 Middleware 捕获所有视图异常
中间件在视图执行出错后立即介入,能捕获 Exception 及其任意子类(包括你自定义的业务异常),且不侵入 DRF 的异常处理链。关键点:
-
process_exception必须显式返回JsonResponse或HttpResponse,否则 Django 会继续走默认 500 页面逻辑 - 中间件注册顺序很重要:放在
SecurityMiddleware之后、CommonMiddleware之前,避免状态码被重写 - 不要在
process_exception里做数据库查询或调用可能抛异常的第三方服务,否则可能触发二次异常 - 若项目混用 HTML 和 API,建议加路径判断,比如只对
/api/前缀返回 JSON,其余走默认流程
区分 DRF 异常和原生异常
DRF 自带的 exception_handler 函数只处理 APIException、Http404、PermissionDenied 这三类,且只在 DRF 视图(如 APIView)中生效。普通函数视图或 View 子类抛出的 APIException 不会被它捕获。
- 如果你只用 DRF 写 API,优先重写
REST_FRAMEWORK['EXCEPTION_HANDLER'],它天然支持ValidationError等语义化异常,返回的是Response对象,不用手动设Content-Type - 如果你还用了
TemplateView、RedirectView或函数视图,就必须靠中间件兜底——DRF 的 handler 对它们完全无效 - 自定义异常类应继承
Exception而非APIException,否则中间件里isinstance(exception, MyCustomError)才能匹配上
构造 JsonResponse 时的硬性要求
JsonResponse 看似简单,但漏掉参数就会失败:
librosa 是一个用于音频和音乐分析的 Python 库。它提供了特征提取、频谱分析、节拍跟踪、起始检测和音频可视化的工具,基于 NumPy 和 SciPy 构建,用于科学音频计算。
- 必须传
status=xxx,不能只靠response.status_code = 400,某些客户端(如旧版 axios)会忽略响应头里的状态码 - 返回 dict 没问题;如果想返回 list(例如批量校验错误),必须加
safe=False,否则抛TypeError: In order to allow non-dict objects to be serialized - 生产环境禁用
DEBUG=True时,别把traceback.format_exc()直接塞进响应体,这是安全风险 - 推荐统一用枚举类管理错误码和文案,比如
ResponseEntity.VALIDATION_ERROR.status,避免魔法数字散落各处
404 和 500 页面不能靠中间件处理
process_exception 不会捕获 Http404 或 PermissionDenied ——它们被 Django 内部提前拦截并转为 404/403 响应,根本不会走到你的中间件。要自定义这些页面:
- 404:在根
urls.py设置handler404 = 'myapp.views.custom_404_view',函数签名是def custom_404_view(request, exception) - 500:同理设
handler500,但注意该函数内禁止任何可能出错的操作(比如查数据库),否则会陷入无限 500 循环 - 这两个 handler 返回的是渲染后的
HttpResponse,不是JsonResponse,别混淆
真正容易被忽略的是:中间件对异步视图(async def my_view)默认不生效,Django 5+ 要求中间件也得是异步的(实现 __acall__),否则会报 RuntimeWarning: Synchronous middleware ... called asynchronously。如果你用了 async view,得单独适配。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










