Django实现Slack错误上报功能的相关问题咨询
问题解答
问题1:无法从响应中获取message字段报错KeyError
- 原因:DRF的
Response实例返回的业务数据存储在.data属性中,不能直接通过字典键访问响应对象本身 - 解决方法:先从
response.data中取值,同时添加类型判断避免非字典响应的报错
修正后的中间件对应代码:
def process_template_response(self, request, response): if response.status_code >= 400: # 先判断data是否为字典类型,再取message error_msg = response.data.get('message') if isinstance(response.data, dict) else str(response.data) error_reporting(request, error_msg=error_msg) return response
问题2:中间件中无法获取query_params报错AttributeError
- 原因:
query_params是DRF封装后的请求对象才有的属性,中间件拿到的是原生DjangoWSGIRequest对象,没有该属性 - 解决方法:用原生Django请求的属性取值:
- 查询参数直接从
request.GET获取,调用.dict()可以转成标准字典格式 - 请求payload根据Content-Type分别处理:表单格式从
request.POST获取,JSON格式需要解析request.body
示例获取请求参数的代码:
- 查询参数直接从
import json def error_reporting(request, error_msg=None): # 获取查询参数 query_params = request.GET.dict() # 获取请求payload payload = {} if request.method in ("POST", "PUT", "PATCH"): if request.content_type == "application/json": try: payload = json.loads(request.body) except json.JSONDecodeError: payload = {"raw_body": request.body.decode("utf-8", errors="ignore")} else: payload = request.POST.dict() # 后续发Slack逻辑 return 'error reported successfully'
问题3:其他实现方案推荐
方案1:自定义DRF异常处理器(最推荐,和业务耦合度最低)
DRF所有未捕获的异常都会走全局异常处理器,直接在这里处理错误上报即可,不需要中间件全局判断所有请求:
from rest_framework.views import exception_handler def custom_exception_handler(exc, context): response = exception_handler(exc, context) if response is not None and response.status_code >=400: request = context['request'] error_msg = response.data.get('message') if isinstance(response.data, dict) else str(exc) # 调用发Slack的函数 error_reporting(request, error_msg) return response
之后在settings.py中注册该异常处理器即可:
REST_FRAMEWORK = { 'EXCEPTION_HANDLER': '你的模块路径.custom_exception_handler' }
方案2:日志系统对接Slack
使用Python logging模块自定义Slack日志处理器,所有错误日志自动推送至Slack,还可以支持日志分级、采样等高级能力,适用场景更广。
方案3:Django信号机制
自定义错误触发信号,在API捕获异常返回400的时候发送信号,由信号接收器执行推送Slack的逻辑,业务代码和上报逻辑完全解耦。
内容的提问来源于stack exchange,提问作者Aman Sharma
相关产品推荐
相关产品推荐

