如何在 DRF 中捕获所有 500 个及以上的错误并记录它们?

How can I catch all 500 and above errors in DRF and log them?

我已经查看了很多有关实现此功能的 SO 响应,但我似乎找不到未弃用的内容或实际适用于我的用例的内容。

基本上,我有一些 API 方法 return 它们自己的状态代码。但是,如果由于任何原因出现 500 服务器错误或任何高于 500 的错误表明发生了一些奇怪的事情(例如,假设数据库连接超时),我希望将其记录到文件或 e-mailed管理员。

我试过使用自定义异常处理程序,但并非所有 500 错误都是异常。

所以我求助于编写自定义中间件,它看起来像这样

class CustomApiLoggingMiddleware(MiddlewareMixin):
    def process_response(self, request, response):
        if response.path.startswith('/api/'):
            ...do stuff here

然而,问题是似乎没有 status_code。坦率地说,我真的不知道我实际上得到了哪种回应。作为 API 方法的结果,我的 API 有意 return 编辑了 500 响应,如果不满足某种条件,后端会生成 Django 生成的 500 响应(假设他们发送了一个没有正确 header 的请求)

我试图通过 returning Response(status=status.HTTP_500) 在一些基本的 /500 路由中故意生成 500 响应/错误。尽管这会触发中间件,但我无法使用 status_code 来检查响应是否实际上是 500。

我什至不确定我这样做是否正确,但希望您能理解我的意图。我基本上想全面捕获由于我的 API 调用而可能发生的所有未捕获异常,并将它们记录下来或将它们发送给管理员。大多数 return 大约 40X 或其他任何调用都以我想要的方式处理。

我并不完全熟悉 MiddlewareMixin,但是 docs 中描述的使用可调用 class 的直接实现似乎可行:

class ResponseStatusMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        response = self.get_response(request)
        print(f"Response has status {response.status_code}")

        return response

当视图 return HttpResponse(status=500) 使用标准 Django HttpResponse 时,这工作正常。但是,当视图引发异常时,由于 Django Rest Framework 的异常处理,中间件可能会被绕过。如果 get_response 引发异常,您可以通过在中间件中实现 process_exception 挂钩来处理它:

class ResponseStatusMiddleware:
    ...
    def process_exception(self, request, exception):
        ...log your exception...

您还可以使用自定义处理程序将未捕获的异常转换为响应对象,或者,如果可能,将它们转换为自动处理的 DRF APIException

此外,status.HTTP_500 可能应该是 status.HTTP_500_INTERNAL_SERVER_ERROR(参见 the DRF documentation)。