Django中如何将异常信息传递给500错误处理视图?
Django自定义500错误视图无法获取异常对象
我配置了自定义500错误处理:
urls.py
handler500 = 'main.views_error.view_error_500'
main/views_error.py
def view_error_500(request, exception=None): print("APP: view_error_500") print(exception) return render(request,"error/500.html", status=500)
触发500错误时,控制台打印exception为None,但日志中存在完整异常栈信息:
APP: view_error_500 None 2024-02-04 18:24:58,641 - django.request 241 - ERROR - Internal Server Error: /office/order_14841/ Traceback (most recent call last): File "/usr/local/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner response = get_response(request) ^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/site-packages/django/core/handlers/base.py", line 197, in _get_response response = wrapped_callback(request, *callback_args, **callback_kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/site-packages/django/contrib/auth/decorators.py", line 23, in _wrapper_view return view_func(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/site-packages/django/contrib/auth/decorators.py", line 23, in _wrapper_view return view_func(request, *args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/code/main/views_admin.py", line 1453, in admin_orders_edit order = Company_Orders.objects.get(id=kwargs["order_id"]) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/site-packages/django/db/models/manager.py", line 87, in manager_method return getattr(self.get_queryset(), name)(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/usr/local/lib/python3.12/site-packages/django/db/models/query.py", line 647, in get raise self.model.DoesNotExist( main.models.Company_Orders.DoesNotExist: Company_Orders matching query does not exist.
确认已配置错误处理视图,但异常未传递到视图中,如何让错误处理视图获取错误信息?
解决方案
核心原因
Django在DEBUG=False的生产环境下,出于安全考量,不会直接将异常对象传递给handler500视图,因此exception参数默认是None,但完整异常信息会被记录到系统日志中。
方法1:利用ExceptionReporter获取异常详情
使用Django内置的ExceptionReporter类,从当前异常上下文提取错误信息:
修改main/views_error.py:
import sys from django.shortcuts import render from django.views.debug import ExceptionReporter def view_error_500(request): print("APP: view_error_500") # 生成异常报告器,获取当前异常上下文 reporter = ExceptionReporter(request, *sys.exc_info()) # 获取异常对象 exception = reporter.exc_value print(exception) # 可选:获取完整栈追踪文本 traceback_text = reporter.get_traceback_text() print(traceback_text) return render(request,"error/500.html", status=500)
方法2:自定义中间件捕获异常
通过中间件在异常发生时将其附加到request对象,再在500视图中读取:
- 创建
main/middleware.py:
class ExceptionCaptureMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): return self.get_response(request) def process_exception(self, request, exception): # 将异常绑定到request对象 request.exception = exception # 返回None让Django继续调用handler500处理错误 return None
- 在
settings.py中注册中间件:
MIDDLEWARE = [ # ... 其他中间件 'main.middleware.ExceptionCaptureMiddleware', ]
- 修改500视图:
def view_error_500(request, exception=None): print("APP: view_error_500") # 优先从request获取异常,兼容原有参数 current_exception = getattr(request, 'exception', exception) print(current_exception) return render(request,"error/500.html", status=500)
注意事项
- 生产环境中禁止向前端页面展示完整异常信息,避免泄露敏感代码或数据库细节,仅保留服务器端日志记录即可。
- 若使用
ExceptionReporter,需确保代码运行在异常发生的上下文环境中,sys.exc_info()才能正确获取异常数据。
内容的提问来源于stack exchange,提问作者Yuretz
相关产品推荐
相关产品推荐

