1
0
forked from erp-dev/erp
Files
erpnew/flower/exception_handler.py

102 lines
3.6 KiB
Python

from rest_framework import exceptions, status
from rest_framework.response import Response
from rest_framework.views import exception_handler
from rest_framework_simplejwt.exceptions import InvalidToken
from flower.error_code import AuthErrorCode
def auth_error_response(*, error_code: AuthErrorCode, code: str, message: str, http_status: int, extra=None):
data = {
'error_code': int(error_code),
'code': code,
'message': message,
'detail': message,
}
if extra:
data.update(extra)
return Response(data, status=http_status)
def _stringify_detail(detail):
if hasattr(detail, 'code'):
return str(detail), str(detail.code)
return str(detail), None
def _extract_exception_detail(exc):
detail = getattr(exc, 'detail', None)
if isinstance(detail, dict):
raw_detail = detail.get('detail')
raw_code = detail.get('code')
messages = detail.get('messages')
message = str(raw_detail) if raw_detail is not None else ''
code = str(raw_code) if raw_code is not None else None
extra = {'messages': messages} if messages is not None else None
return message, code, extra
message, code = _stringify_detail(detail)
return message, code, None
def custom_exception_handler(exc, context):
if isinstance(exc, InvalidToken):
_, _, extra = _extract_exception_detail(exc)
return auth_error_response(
error_code=AuthErrorCode.TOKEN_NOT_VALID,
code='token_not_valid',
message='Token 无效或已过期',
http_status=status.HTTP_401_UNAUTHORIZED,
extra=extra,
)
if isinstance(exc, exceptions.NotAuthenticated):
return auth_error_response(
error_code=AuthErrorCode.NOT_AUTHENTICATED,
code='not_authenticated',
message='未提供认证凭据',
http_status=status.HTTP_401_UNAUTHORIZED,
)
if isinstance(exc, exceptions.AuthenticationFailed):
message, code, extra = _extract_exception_detail(exc)
if code == 'bad_authorization_header':
return auth_error_response(
error_code=AuthErrorCode.BAD_AUTHORIZATION_HEADER,
code='bad_authorization_header',
message='Authorization 请求头格式错误',
http_status=status.HTTP_401_UNAUTHORIZED,
)
if code == 'user_not_found':
return auth_error_response(
error_code=AuthErrorCode.TOKEN_USER_NOT_FOUND,
code='token_user_not_found',
message='Token 对应用户不存在',
http_status=status.HTTP_401_UNAUTHORIZED,
)
if code == 'user_inactive':
return auth_error_response(
error_code=AuthErrorCode.TOKEN_USER_INACTIVE,
code='token_user_inactive',
message='Token 对应用户已被禁用',
http_status=status.HTTP_401_UNAUTHORIZED,
)
return auth_error_response(
error_code=AuthErrorCode.TOKEN_NOT_VALID,
code=code or 'authentication_failed',
message=message or '认证失败',
http_status=status.HTTP_401_UNAUTHORIZED,
extra=extra,
)
if isinstance(exc, exceptions.PermissionDenied):
return auth_error_response(
error_code=AuthErrorCode.PERMISSION_DENIED,
code='permission_denied',
message='无权限访问该资源',
http_status=status.HTTP_403_FORBIDDEN,
)
return exception_handler(exc, context)