mirror of https://github.com/jumpserver/jumpserver
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
63 lines
2.1 KiB
63 lines
2.1 KiB
import traceback |
|
from logging import getLogger |
|
|
|
from django.core.exceptions import PermissionDenied, ObjectDoesNotExist as DJObjectDoesNotExist |
|
from django.db.models.deletion import ProtectedError |
|
from django.http import Http404 |
|
from django.utils.translation import gettext |
|
from django.conf import settings |
|
from rest_framework import exceptions |
|
from rest_framework.response import Response |
|
from rest_framework.views import set_rollback |
|
|
|
from common.exceptions import JMSObjectDoesNotExist, ReferencedByOthers |
|
|
|
logger = getLogger('drf_exception') |
|
unexpected_exception_logger = getLogger('unexpected_exception') |
|
|
|
|
|
def extract_object_name(exc, index=0): |
|
""" |
|
`index` 是从 0 开始数的, 比如: |
|
`No User matches the given query.` |
|
提取 `User`,`index=1` |
|
""" |
|
if exc.args: |
|
(msg, *others) = exc.args |
|
else: |
|
return gettext('Object') |
|
return gettext(msg.split(sep=' ', maxsplit=index + 1)[index]) |
|
|
|
|
|
def common_exception_handler(exc, context): |
|
if settings.DEBUG_DEV: |
|
logger.exception('Print traceback exception for Debug') |
|
traceback.print_exc() |
|
|
|
if isinstance(exc, Http404): |
|
exc = JMSObjectDoesNotExist(object_name=extract_object_name(exc, 1)) |
|
elif isinstance(exc, PermissionDenied): |
|
exc = exceptions.PermissionDenied() |
|
elif isinstance(exc, DJObjectDoesNotExist): |
|
exc = JMSObjectDoesNotExist(object_name=extract_object_name(exc, 0)) |
|
elif isinstance(exc, ProtectedError): |
|
exc = ReferencedByOthers() |
|
|
|
if isinstance(exc, exceptions.APIException): |
|
headers = {} |
|
if getattr(exc, 'auth_header', None): |
|
headers['WWW-Authenticate'] = exc.auth_header |
|
if getattr(exc, 'wait', None): |
|
headers['Retry-After'] = '%d' % exc.wait |
|
|
|
if isinstance(exc.detail, str) and isinstance(exc.get_codes(), str): |
|
data = {'detail': exc.detail, 'code': exc.get_codes()} |
|
else: |
|
data = exc.detail |
|
|
|
set_rollback() |
|
return Response(data, status=exc.status_code, headers=headers) |
|
else: |
|
unexpected_exception_logger.exception('') |
|
|
|
return None
|
|
|