python - 明智地利用ATOMIC_REQUESTS处理 500处理程序中的一些错误并在这些情况下呈现正常的HTTP响应

  显示原文与译文双语对照的内容

启用 ATOMIC_REQUESTS 时,每个视图都包装在事务中。 如果视图引发异常,则回滚事务,这很方便。 问题是,你必须允许异常传播到视图中,因这里你将得到 HTTP 500作为结果。

to使用 ATOMIC_REQUESTS,认为必须用我们自己的实现重写 handler500,这样可以检查导致错误的异常,并在适当的情况下提供正常的用户友好 HTTP 200响应,即在 DEBUG 模式下的堆栈跟踪或者默认的Django handler500

: )


class UserFriendlyError(Exception):
 pass

def my_view(request):
 # Do some database work here...
 if request.GET['foo'] == 'bar': # Some condition
 # The idea is to show this to user. my_custom_handler500 would handle this
 raise UserFriendlyError("Don't do this, this is deprecated -- do that instead")
 # Normal exceptions can happen too and would provide a real HTTP 500 instead
 #.. .

def my_custom_500(request):
 ex = sys.exc_info()[1]
 if isinstance(ex, UserFriendlyError):
 # Return a normal 200 response
 return render(request, 'user_friendly_error.html', {'exception': ex})
 # Otherwise fall back to the default handler
 return django.views.defaults.server_error(request)

有关更多背景信息,请参见

问题是,当 DEBUG 模式处于活动状态时,handler500 机器在堆栈跟踪调试处理程序中绕过 但是,为了进行这项工作,仍然应该在 DEBUG 模式下调用自定义 500处理程序,而不是默认的500处理程序。

有一种方法可以做到这一点,最好不要黑进 Django 。 或者有一个更好的方法来做同样的事情,不是?

时间: 作者:

实现你自己的中间件似乎是。 把它放在 MIDDLEWARE_CLASSES 列表的末尾,并在其中实现 process_exception,e.g.


class MyMiddleware(object):
"""Handles UserFriendlyError"""
 def process_exception(self, request, exception):
 if isinstance(exception, UserFriendlyError):
 return render(request, 'user_friendly_error.html', {'exception': exception})
 else:
 return None

# In your settings.py
MIDDLEWARE_CLASSES = (
 #.. .
 'myproject.mymiddleware.MyMiddleware',
)

只有7 行代码和预期的工作,无论 DEBUG 模式,而且不修补 500处理程序所在。

作者:
...