115 lines
4.0 KiB
Python
115 lines
4.0 KiB
Python
# -*- coding: utf-8 -*-
|
||
|
||
"""
|
||
@Remark: 自定义异常处理
|
||
"""
|
||
import logging
|
||
import traceback
|
||
|
||
from django.db.models import ProtectedError
|
||
from django.db.utils import DatabaseError
|
||
from rest_framework import exceptions
|
||
from rest_framework.exceptions import APIException as DRFAPIException, AuthenticationFailed,NotAuthenticated,ValidationError,NotFound
|
||
from rest_framework.views import set_rollback,exception_handler
|
||
from django.http.response import Http404
|
||
|
||
from utils.jsonResponse import ErrorResponse
|
||
|
||
logger = logging.getLogger(__name__)
|
||
|
||
|
||
def CustomExceptionHandler(ex, context):
|
||
"""
|
||
统一异常拦截处理
|
||
目的:(1)取消所有的500异常响应,统一响应为标准错误返回
|
||
(2)准确显示错误信息
|
||
:param ex:
|
||
:param context:
|
||
:return:
|
||
"""
|
||
msg = ''
|
||
code = 4000
|
||
response = exception_handler(ex, context)
|
||
if isinstance(ex, AuthenticationFailed):
|
||
code = 4001
|
||
if 'User is inactive' in str(ex.detail):
|
||
msg = "该账号已被禁用,请联系管理员"
|
||
elif response and response.data.get("detail") == "Given token not valid for any token type":
|
||
msg = "身份认证已过期"
|
||
else:
|
||
msg = ex.detail
|
||
elif isinstance(ex, NotAuthenticated):
|
||
code = 4001
|
||
msg = ex.detail
|
||
# elif isinstance(ex,NotFound):
|
||
# if str(ex)=="无效页面。":
|
||
# msg="暂无数据"
|
||
# else:
|
||
# msg = str(ex)
|
||
elif isinstance(ex, exceptions.ValidationError):
|
||
msg = ex.detail
|
||
errorMsg = msg
|
||
try:
|
||
for key in errorMsg:
|
||
if key:
|
||
msg = '%s:%s' % (key, errorMsg[key][0])
|
||
else:
|
||
msg = errorMsg[key][0]
|
||
except:
|
||
# {comment_author: {non_field_errors: ["无效数据。期待为字典类型,得到的是 str 。"]}, images: ["Not a valid string."]}
|
||
if isinstance(errorMsg, list):
|
||
msg = errorMsg[0]
|
||
elif isinstance(errorMsg, dict):
|
||
values_list = list(errorMsg.values())
|
||
keys_list = list(errorMsg.keys())
|
||
if 'non_field_errors' in values_list[0]:
|
||
msg = keys_list[0] + ":" + values_list[0]['non_field_errors'][0]
|
||
elif isinstance(values_list[0], list):
|
||
msg = keys_list[0] + ":" + values_list[0][0]
|
||
else:
|
||
msg = errorMsg[0]
|
||
else:
|
||
msg = errorMsg
|
||
elif 'django.db.utils.IntegrityError' in str(type(ex)):
|
||
msg=str(ex)
|
||
res = msg.split(', ')
|
||
if res[0] == '(1062':
|
||
msg="数据有重复,请检查后重试:%s"%msg
|
||
elif isinstance(ex,Http404):
|
||
code = 404
|
||
msg = "404错误:您访问的地址不存在"
|
||
elif isinstance(ex, DRFAPIException):
|
||
set_rollback()
|
||
msg = str(ex.detail)
|
||
elif isinstance(ex, exceptions.APIException):
|
||
set_rollback()
|
||
msg = ex.detail
|
||
elif isinstance(ex, ProtectedError):
|
||
set_rollback()
|
||
msg = "删除失败:该条数据与其他数据有相关绑定"
|
||
# elif isinstance(ex, DatabaseError):
|
||
# set_rollback()
|
||
# msg = "接口服务器异常,请联系管理员"
|
||
elif isinstance(ex, Exception):
|
||
logger.error(traceback.format_exc())
|
||
msg = str(ex)#原样输出错误
|
||
|
||
# errorMsg = msg
|
||
# for key in errorMsg:
|
||
# msg = errorMsg[key][0]
|
||
# print(traceback.format_exc())
|
||
return ErrorResponse(msg=msg, code=code)
|
||
|
||
|
||
class APIException(Exception):
|
||
"""
|
||
通用异常:(1)用于接口请求是抛出移除, 此时code会被当做标准返回的code, message会被当做标准返回的msg
|
||
"""
|
||
|
||
def __init__(self, code=201, message='API异常', args=('API异常',)):
|
||
self.args = args
|
||
self.code = code
|
||
self.message = message
|
||
|
||
def __str__(self):
|
||
return self.message |