通过处理500处理程序中的一些错误并在这些情况下提供正常的HTTP响应,明智地利用原子请求

2024-03-28 23:11:15 发布

您现在位置:Python中文网/ 问答频道 /正文

启用ATOMIC_REQUESTS时,每个视图都包装在一个事务中。如果视图引发异常,事务将回滚,这很方便。问题是,您必须允许异常通过视图传播,结果会得到HTTP500。你知道吗

因此,为了利用ATOMIC_REQUESTS,它认为有必要用我们自己的实现覆盖handler500,这将检查导致错误的异常,并在适当的情况下提供一个正常的用户友好的http200响应,否则返回到默认响应,它是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)

有关更多背景信息,请参见this question。你知道吗

问题是,当DEBUG模式激活时,handler500机制是circumvented with the stack trace debug handler。但是,要使这项工作正常,自定义500处理程序仍应在DEBUG模式下调用,但应返回到调试堆栈跟踪处理程序,而不是默认的500处理程序。你知道吗

有没有一种方法能让这一切顺利进行,最好是不伤Django的肠子?或者也许有更好的方法来做同样的事情,不是吗?你知道吗


Tags: todebug视图处理程序堆栈requestmy模式
1条回答
网友
1楼 · 发布于 2024-03-28 23:11:15

实现自己的中间件似乎是一种可行的方法。只需将它放在MIDDLEWARE_CLASSES列表的末尾,并在其中实现process_exception,例如

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',
)

不管DEBUG模式如何,只需要七行代码就可以正常工作,而且根本不需要修改500处理程序。你知道吗

相关问题 更多 >