def exception_handler(exc, context=None): """ Returns the response that should be used for any given exception. By default we handle the REST framework `APIException` and Django's builtin `Http404` exceptions. Any unhandled exceptions are caught and logged by this handler and an `OperationException` is raised accordingly the view or process behind that triggered the actual error. """ if isinstance(exc, Http404): exc = NotFound() elif isinstance(exc, ValidationError): exc = InvalidInputException(errors=exc.detail) # Make sure we always working with an APIException if not isinstance(exc, (APIException, BaseException)): raise exc identifier = getattr(exc, "identifier", None) code = getattr(exc, "code", "") message = getattr(exc, "message", "") error_code = getattr(exc, "error_code", "") errors = getattr(exc, "errors", []) if not code and isinstance(exc, APIException): # DRF 3.5 exceptions have a proper code we can expose if hasattr(exc, "get_codes"): codes = exc.get_codes() if isinstance(codes, string_types): code = codes else: code = next(iter(codes)) # Fallback to the default OPERATION_FAILED message # if also no default_code was provided code = code or getattr(exc, "default_code", "OPERATION_FAILED") code = code.upper() if isinstance(exc, MethodNotAllowed): code = "NOT_ALLOWED" elif isinstance(exc, NotFound): code = "NOT_FOUND" data = dict(message=message, errors=errors, key=identifier, code=code, error_code=error_code) return Response(data, status=exc.status_code)
def custom_exception_handler(exc, context): """捕获rest framework 错误异常,返回自定义的错误格式""" if isinstance(exc, Http404): exc = NotFound() elif isinstance(exc, HttpResponseForbidden): exc = PermissionDenied() response = exception_handler(exc=exc, context=context) if response and isinstance(response.data, dict): detail = response.data.pop('detail', None) if detail: response.data['error'] = detail if hasattr(exc, 'get_codes'): response.data['code'] = exc.get_codes() return response