Django 如何全局捕获异常和DEBUG

DEBUG

默认:False

一个开启、关闭调试模式的布尔值。

永远不要在 DEBUG 开启的情况下将网站部署到生产中。

调试模式的主要功能之一是显示详细的错误页面。如果你的应用程序在 DEBUG 为 True 时引发了异常,Django 会显示一个详细的回溯,包括很多关于你的环境的元数据,比如所有当前定义的 Django 配置(来自 settings.py)。

视图抛出异常

Django 和 Django-rest-framework 中视图最终都是集成 class APIView(View),从 APIView 中查看,所有的请求都是通过 dispatch 这个方法分发:

python 复制代码
def dispatch(self, request, *args, **kwargs):
    """
    `.dispatch()` is pretty much the same as Django's regular dispatch,
    but with extra hooks for startup, finalize, and exception handling.
    """
    self.args = args
    self.kwargs = kwargs
    request = self.initialize_request(request, *args, **kwargs)
    self.request = request
    self.headers = self.default_response_headers  # deprecate?

    try:
        self.initial(request, *args, **kwargs)

        # Get the appropriate handler method
        if request.method.lower() in self.http_method_names:
            handler = getattr(self, request.method.lower(),
                              self.http_method_not_allowed)
        else:
            handler = self.http_method_not_allowed

        response = handler(request, *args, **kwargs)

    except Exception as exc:
        response = self.handle_exception(exc)   # 抛出异常

    self.response = self.finalize_response(request, response, *args, **kwargs)
    return self.response

response = self.handle_exception(exc) 中:

python 复制代码
    def handle_exception(self, exc):
        """
        Handle any exception that occurs, by returning an appropriate response,
        or re-raising the error.
        """
        if isinstance(exc, (exceptions.NotAuthenticated,
                            exceptions.AuthenticationFailed)):
            # WWW-Authenticate header for 401 responses, else coerce to 403
            auth_header = self.get_authenticate_header(self.request)

            if auth_header:
                exc.auth_header = auth_header
            else:
                exc.status_code = status.HTTP_403_FORBIDDEN

        exception_handler = self.get_exception_handler()

        context = self.get_exception_handler_context()
        response = exception_handler(exc, context)

        if response is None:
            self.raise_uncaught_exception(exc)  # 异常部分

        response.exception = True
        return response

self.raise_uncaught_exception(exc) 中:

会通过 DEBUG 判读是否是开发模式,如果是开发模式通过 request 包装器返回,如果不是会重新抛出最近的异常。

python 复制代码
    def raise_uncaught_exception(self, exc):
        if settings.DEBUG:
            request = self.request
            renderer_format = getattr(request.accepted_renderer, 'format')
            use_plaintext_traceback = renderer_format not in ('html', 'api', 'admin')
            request.force_plaintext_errors(use_plaintext_traceback)
        raise  # 重新抛出最近的异常

全局捕获

视图抛出异常之后,怎么处理异常,如果不处理前端会抛出一个显示详细的错误页面。如果你的应用程序在 DEBUG 为 True 时引发了异常,Django 会显示一个详细的回溯,包括很多关于你的环境的元数据,比如所有当前定义的 Django 配置,暴露太多内容,对网站会非常不安全。解决办法,定义一个全局的异常捕获,如果有异常,这返回一个可视化的信息给起前端。

python 复制代码
class AppExceptionMiddleware(MiddlewareMixin):

    def process_exception(self, request, exception):
        self.exception = exception
        self.request = request

        # 用户自我感知的异常抛出
        if isinstance(exception, BlueException):
            logger.log(
                exception.LOG_LEVEL,
                (u"""捕获主动抛出异常, 具体异常堆栈->[%s] status_code->[%s] & """
                 u"""client_message->[%s] & args->[%s] """) % (
                    traceback.format_exc(),
                    exception.ERROR_CODE,
                    exception.message,
                    exception.args
                )
            )

            response = JsonResponse(exception.response_data())

            response.status_code = exception.STATUS_CODE
            return response

        response = JsonResponse({
            "result": False,
            'code': "50000",
            'message': _(u"系统异常,请联系管理员处理"),
            'data': None
        })
        response.status_code = 500

        # notify sentry
        if sentry_exception_handler is not None:
            sentry_exception_handler(request=request)

        return response

效果

相关推荐
xj757306533几秒前
《精通Django》第一章 入门
数据库·django·sqlite
程序员杰哥2 分钟前
操作自动化测试如何实现用例设计实例?
自动化测试·软件测试·python·功能测试·测试工具·测试用例·接口测试
山沐与山3 分钟前
【Go】Go环境搭建与第一个程序
开发语言·后端·golang
nuowenyadelunwen3 分钟前
Harvard CS50 week 7 Problem Sets Solutions
数据库·sql·harvard cs50·cs50 week7
JosieBook3 分钟前
【数据库】时序数据智能基座:Apache IoTDB 选型与深度实践指南
数据库·apache·iotdb
rgeshfgreh5 分钟前
Redis7持久化机制全解析
python
Gauss松鼠会5 分钟前
【GaussDB】跨用户调用已授权的存储过程,可能会在存储过程内SQL的自定义函数表达式里报错没有权限
数据库·sql·database·gaussdb
热心不起来的市民小周6 分钟前
说的神马?基于 Wav2Vec2 的端到端中文语音识别系统
人工智能·python·语音识别
lixzest6 分钟前
C++应用开发转到大模型应用开发路径
开发语言·c++·人工智能·python
BingoGo6 分钟前
2026 年 PHP 的三大优势 这门"老将"为何依然重要
后端·php