import logging import traceback from rest_framework import exceptions from rest_framework.views import set_rollback from .request_util import get_verbose_name from .response import ErrorResponse logger = logging.getLogger(__name__) from rest_framework.exceptions import APIException as DRFAPIException, AuthenticationFailed 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 class GenException(APIException): pass class FrameworkException(Exception): """ 框架异常、配置异常等 """ def __init__(self, message='框架异常', *args: object, **kwargs: object) -> None: super().__init__(*args, ) self.message = message def __str__(self) -> str: return f"{self.message}" class JWTAuthenticationFailedException(APIException): """ JWT认证异常 """ def __init__(self, code=201, message=None, args=('异常',)): if not message: message = 'JWT authentication failed!' super().__init__(code, message, args) def op_exception_handler(ex, context): """ 统一异常拦截处理 目的:(1)取消所有的500异常响应,统一响应为标准错误返回 (2)准确显示错误信息 :param ex: :param context: :return: """ msg = '' code = '201' request = context.get('request') request.session['model_name'] = str(get_verbose_name(view=context.get('view'))) if isinstance(ex, AuthenticationFailed): code = 401 msg = ex.detail elif isinstance(ex, DRFAPIException): set_rollback() msg = ex.detail elif isinstance(ex, exceptions.APIException): set_rollback() msg = ex.detail elif isinstance(ex, Exception): logger.error(traceback.format_exc()) msg = str(ex) return ErrorResponse(msg=msg, code=code)