Last active
October 19, 2020 01:10
-
-
Save CryceTruly/1875084d55cde34bb01f973460f6ce52 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from rest_framework.views import exception_handler | |
from rest_framework import status | |
from django.http import Http404 | |
def custom_exception_handler(exc, context): | |
""" | |
This function will handle errors that are returned by | |
the different views. | |
The `handlers` dictionary will map | |
each exception name to the function that should handle it. | |
Each function should return a response with a message | |
and the actual error. | |
""" | |
# We Call REST framework's default exception handler first | |
response = exception_handler(exc, context) | |
handlers = { | |
'ValidationError': _handle_generic_error, | |
'Http404': _handle_generic_error, | |
'PermissionDenied': _handle_generic_error, | |
'NotAuthenticated': _handle_authentication_error | |
} | |
exception_class = exc.__class__.__name__ | |
# Now we add the HTTP status code to the response when its in the context | |
# of the LoginAPIVIew. | |
if response is not None: | |
# Raising a NotAuthenticatedError should send a 401 response status | |
# code, however due to the Authentication scheme used by our | |
# application it raises 403 instead. This calls for the need to | |
# write a custom exception handler and make it send a 401 in the | |
# context of login | |
response = _handle_generic_error(exc, context, response) | |
response.data['status_code'] = response.status_code | |
if "AuthUserAPIView" in str(context['view']) and exc.status_code == 401: | |
response.status_code = status.HTTP_200_OK | |
response.data = {'is_logged_in': False} | |
return response | |
if exception_class in handlers: | |
return handlers[exception_class](exc, context, response) | |
return response | |
def _handle_generic_error(exc, context, response): | |
# We take the response generated by DRF and wrap it in the `errors` key | |
return response | |
def _handle_authentication_error(exc, context, response): | |
"""If users are not logged in, we return this custom response""" | |
response.data = { | |
'error': 'Please log in to proceed.' | |
} | |
response.data['status_code'] = response.status_code | |
return response |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment