Files
django-vue3-admin/backend/dvadmin/utils/exception.py
T

116 lines
3.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""
@author: 猿小天
@contact: QQ:1638245306
@Created on: 2021/6/2 002 16:06
@Remark: 自定义异常处理
"""
import logging
import traceback
from django.db.models import ProtectedError
from django.http import Http404
from rest_framework.exceptions import APIException as DRFAPIException, AuthenticationFailed, NotAuthenticated
from rest_framework.status import HTTP_401_UNAUTHORIZED
from rest_framework.views import set_rollback, exception_handler
from dvadmin.utils.json_response import ErrorResponse
logger = logging.getLogger(__name__)
def _format_drf_detail(detail):
"""
将 DRF ValidationError.detail 转为可读字符串。
避免嵌套列表(如 items 多行明细)在简单拼接时只剩「items:{}」等无效提示。
"""
if detail is None:
return ""
if isinstance(detail, dict):
if not detail:
return ""
parts = []
for k, v in detail.items():
if isinstance(v, (list, tuple)):
subs = []
for item in v:
if isinstance(item, dict):
inner = _format_drf_detail(item)
if inner:
subs.append(inner)
else:
subs.append(str(item))
if subs:
parts.append("%s: %s" % (k, ";".join(subs)))
elif isinstance(v, dict):
inner = _format_drf_detail(v)
if inner:
parts.append("%s: %s" % (k, inner))
else:
parts.append("%s: %s" % (k, v))
return ";".join(parts)
if isinstance(detail, (list, tuple)):
subs = []
for item in detail:
if isinstance(item, dict):
inner = _format_drf_detail(item)
if inner:
subs.append(inner)
else:
subs.append(str(item))
return ";".join(subs)
return str(detail)
class CustomAuthenticationFailed(NotAuthenticated):
# 设置 status_code 属性为 400
status_code = 400
def CustomExceptionHandler(ex, context):
"""
统一异常拦截处理
目的:(1)取消所有的500异常响应,统一响应为标准错误返回
(2)准确显示错误信息
:param ex:
:param context:
:return:
"""
msg = ''
code = 4000
# 调用默认的异常处理函数
response = exception_handler(ex, context)
if isinstance(ex, AuthenticationFailed):
# 如果是身份验证错误
if response and response.data.get('detail') == "Given token not valid for any token type":
code = 401
msg = ex.detail
elif response and response.data.get('detail') == "Token is blacklisted":
# token在黑名单
return ErrorResponse(status=HTTP_401_UNAUTHORIZED)
else:
code = 401
msg = ex.detail
elif isinstance(ex,Http404):
code = 400
msg = "接口地址不正确"
elif isinstance(ex, DRFAPIException):
set_rollback()
detail = ex.detail
if isinstance(detail, dict):
msg = _format_drf_detail(detail) or str(detail)
elif isinstance(detail, (list, tuple)):
msg = _format_drf_detail(detail) or str(detail)
else:
msg = str(detail)
elif isinstance(ex, ProtectedError):
set_rollback()
msg = "删除失败:该条数据与其他数据有相关绑定"
# elif isinstance(ex, DatabaseError):
# set_rollback()
# msg = "接口服务器异常,请联系管理员"
elif isinstance(ex, Exception):
logger.exception(traceback.format_exc())
msg = str(ex)
return ErrorResponse(msg=msg, code=code)