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