
django 的 `handler500` 视图默认**不接收异常对象参数**,因此直接声明 `exception=none` 并打印 `exception` 总是输出 `none`;需通过 `sys.exc_info()` 或 `traceback.format_exc()` 在视图内部捕获当前未处理的异常上下文。
在 Django 中,handler500(即 500 Internal Server Error 处理器)是一个特殊的全局错误视图,其函数签名不接受 exception 参数——这与 handler404、handler403 等不同。官方文档明确说明:handler500 的调用 signature 仅为 def view_500(request):,Django 不会将异常实例传递给它。因此你在 view_error_500(request, exception=None) 中看到 exception 始终为 None 是完全符合预期的行为。
要获取实际发生的异常信息(如 Company_Orders.DoesNotExist 及完整 traceback),必须在视图内部主动提取当前异常上下文。推荐使用标准库 traceback 模块:
# main/views_error.py
import traceback
from django.shortcuts import render
def view_error_500(request):
# ✅ 正确方式:在 handler500 内部捕获当前异常上下文
exc_type, exc_value, exc_traceback = traceback.sys.exc_info()
# 获取格式化后的完整 traceback 字符串(等效于终端报错内容)
error_text = "".join(traceback.format_exception(exc_type, exc_value, exc_traceback))
print("APP: view_error_500")
print(f"Exception type: {exc_type.__name__}")
print(f"Exception message: {str(exc_value)}")
print("Full traceback:")
print(error_text)
# 可选:将异常信息传入模板用于调试(生产环境请禁用!)
context = {
'error_type': exc_type.__name__,
'error_message': str(exc_value),
'traceback': error_text if settings.DEBUG else None,
}
return render(request, "error/500.html", context, status=500)⚠️ 注意事项:
- sys.exc_info() 仅在异常处理上下文中有效;handler500 被调用时,Django 已处于异常传播末期,因此该调用是安全且可靠的。
- 切勿在生产环境模板中直接渲染 traceback —— 这会暴露敏感路径、代码逻辑和系统信息,存在严重安全风险。建议仅在 DEBUG=True 时启用调试信息。
- 若需记录错误日志,推荐使用 Django 的 logging 框架(如 logger.error("500 error", exc_info=True)),而非依赖 print。
- 确保 urls.py 中的 handler500 配置位于根 URL 配置文件(通常是主 urls.py)中,且不能被 include() 包裹,否则不会生效。
总结:Django 的 handler500 是一个“无参回调”,其设计初衷是提供统一的服务器错误响应页面,而非异常分析接口。如需诊断能力,请结合 sys.exc_info() + traceback.format_exception() 主动提取,并始终遵循安全最佳实践——调试归调试,生产归生产。








