Skip to content

Instantly share code, notes, and snippets.

@CryceTruly
Last active October 19, 2020 01:10
Show Gist options
  • Save CryceTruly/1875084d55cde34bb01f973460f6ce52 to your computer and use it in GitHub Desktop.
Save CryceTruly/1875084d55cde34bb01f973460f6ce52 to your computer and use it in GitHub Desktop.
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