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

效果

相关推荐
十叶知秋25 分钟前
【jmeter】jmeter的线程组功能的详细介绍
数据库·jmeter·性能测试
龙哥说跨境30 分钟前
如何利用指纹浏览器爬虫绕过Cloudflare的防护?
服务器·网络·python·网络爬虫
monkey_meng30 分钟前
【Rust中的迭代器】
开发语言·后端·rust
余衫马33 分钟前
Rust-Trait 特征编程
开发语言·后端·rust
monkey_meng37 分钟前
【Rust中多线程同步机制】
开发语言·redis·后端·rust
小白学大数据1 小时前
正则表达式在Kotlin中的应用:提取图片链接
开发语言·python·selenium·正则表达式·kotlin
flashman9111 小时前
python在word中插入图片
python·microsoft·自动化·word
菜鸟的人工智能之路1 小时前
桑基图在医学数据分析中的更复杂应用示例
python·数据分析·健康医疗
懒大王爱吃狼2 小时前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
瓜牛_gn2 小时前
mysql特性
数据库·mysql