Django 4.0.5无法发送500及以上状态码错误邮件如何排查
Django 4.0.5 500错误管理员邮件不发送排查方案
手动执行mail_admins()可以正常发信,说明SMTP账号、连通性配置完全正常,故障出在错误触发发信的逻辑链上,按优先级逐一排查即可:
- 最高发原因:DEBUG环境变量解析错误
使用django-environ时,直接用env('DEBUG')读取到的是字符串类型,哪怕环境变量里写的是False,实际拿到的是字符串"False",在Python中非空字符串的布尔判断结果为True。Django仅在DEBUG = False(布尔假)时才会触发500错误发信逻辑,DEBUG模式下会直接把错误栈返回给页面,不会发邮件。
验证方式:进入Django shell执行以下代码查看实际值:
如果输出类型为from django.conf import settings print(settings.DEBUG, type(settings.DEBUG))<class 'str'>,把配置改为DEBUG = env.bool('DEBUG', default=False)即可修复。 - 第二高频原因:日志配置覆盖了默认的邮件处理器
很多项目迁移时会自定义LOGGING配置,一旦配置里写了disable_existing_loggers: True,会直接把Django默认挂载的AdminEmailHandler注销,哪怕配了ADMINS也不会触发错误发信。
最小可用的错误发信日志配置参考:LOGGING = { 'version': 1, 'disable_existing_loggers': False, # 必须设为False,否则会覆盖默认日志逻辑 'handlers': { 'mail_admins': { 'level': 'ERROR', 'class': 'django.utils.log.AdminEmailHandler', 'include_html': False, # 如果Gmail拦截邮件可以先关掉HTML格式调试 } }, 'loggers': { 'django.request': { 'handlers': ['mail_admins'], 'level': 'ERROR', 'propagate': True, }, } } - 第三类原因:错误未进入Django请求日志链路
如果错误是在Django处理流程外触发的,根本不会走到发信逻辑:- 反向代理(Nginx等)或应用服务器(Gunicorn/uWSGI等)层面直接返回的502/504/500错误(比如worker超时、应用启动失败、请求体过大被拦截)
- 自定义的异常捕获中间件直接拦截了异常,没有触发
django.request的ERROR级日志记录 - 自定义的500错误视图直接返回响应,没有调用默认的错误日志逻辑
- 第四类原因:发信流程本身执行失败
如果以上配置都正确,去查应用运行时的错误日志,找邮件发送阶段的报错:- 500错误的堆栈内容过大,超过Gmail单封邮件的大小限制导致发信失败(手动发的测试邮件内容小所以能正常发送)
- Gmail将带代码堆栈的邮件判定为可疑垃圾邮件直接拦截,可到发件账号的已发送/拦截记录里排查
AdminEmailHandler配置的异常报告类加载失败,导致发信流程本身抛出异常中断
内容的提问来源于stack exchange,提问作者James
相关产品推荐
相关产品推荐

