import logging import six from django.core.exceptions import PermissionDenied from django.utils.translation import ugettext_lazy as _ from django.http import Http404 from rest_framework import exceptions, status from rest_framework.exceptions import NotAuthenticated, PermissionDenied from rest_framework.response import Response from marshmallow.exceptions import ValidationError from .response import MetaStatus, res_content, APIResponse error_logger = logging.getLogger('exception') def exception_handler(exc, context): """ Returns the response that should be used for any given exception. By default we handle the REST framework `APIException`, and also Django's built-in `Http404` and `PermissionDenied` Any unhandled exceptions may return `None`, which will cause a 500 error to be raised. """ 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, NotAuthenticated) or isinstance(exc, PermissionDenied): data = res_content(MetaStatus.NO_PERMISSION.value, MetaStatus.NO_PERMISSION.verbose_name) elif exc.status_code == 403: data = res_content(MetaStatus.NEED_LOGIN.value, MetaStatus.NEED_LOGIN.verbose_name) else: data = res_content(MetaStatus.INTERNAL_ERROR.value, exc.detail) return Response(data, status=200, headers=headers) elif isinstance(exc, Http404): msg = _('Not found.') data = {'detail': six.text_type(msg)} return Response(data, status=status.HTTP_404_NOT_FOUND) elif isinstance(exc, PermissionDenied): msg = _('Permission denied.') data = {'detail': six.text_type(msg)} return Response(data, status=status.HTTP_403_FORBIDDEN) elif isinstance(exc, ValidationError): meta_status = MetaStatus.INVALID_PARAMS.value # msg = MetaStatus.INVALID_PARAMS.verbose_name return APIResponse(meta_status, msg=str(exc)) elif isinstance(exc, Exception) and hasattr(exc, 'API_META_STATUS'): # msg = exc.API_META_STATUS.verbose_name return APIResponse(exc.API_META_STATUS.value, msg=str(exc)) error_logger.exception('[system error]') return APIResponse(MetaStatus.INTERNAL_ERROR.value, msg=MetaStatus.INTERNAL_ERROR.verbose_name) class NeedLoginException(Exception): API_META_STATUS = MetaStatus.NEED_LOGIN class InvalidParamsException(Exception): API_META_STATUS = MetaStatus.INVALID_PARAMS class InternalErrorException(Exception): API_META_STATUS = MetaStatus.INTERNAL_ERROR class ObjectNotExitException(Exception): API_META_STATUS = MetaStatus.NOT_EXIST class AsyncWaitException(Exception): API_META_STATUS = MetaStatus.ASYNC_WAIT class NoPermissionException(Exception): API_META_STATUS = MetaStatus.NO_PERMISSION class IllegalOperationException(Exception): API_META_STATUS = MetaStatus.ILLEGAL_OPERATION