-
-
Notifications
You must be signed in to change notification settings - Fork 7k
Description
When raising Http404 (django.http.Http404), with a message, e.g:
raise Http404('My custom details')
inside of a function decorated with DRF's api_view (or any class based view, e.g. generics.ListApiView), DRF ignores the details and overwrites them with its own message. The cause are these lines of code in views.py:
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` exceptions.
Any unhandled exceptions may return `None`, which will cause a 500 error
to be raised.
"""
if isinstance(exc, Http404):
exc = exceptions.NotFound()
elif isinstance(exc, PermissionDenied):
exc = exceptions.PermissionDenied()
As you can see, in case of Http404, exc is overriden without any arguments it had (the details) being passed. This can result in a headache when other libraries throw Http404 and you use their functionalities in your api views.
In particular, I was using social-app-django's psa decorator) which in one case throws Http404 with a very important message:
try:
request.backend = load_backend(request.social_strategy,
backend, uri)
except MissingBackend:
raise Http404('Backend not found')
return func(request, backend, *args, **kwargs)
The raised error I got was simply 'Not found' instead of 'Backend not found', which led me to mistakenly believe I've messed something up in my urls. As it stands, other libraries used in conjunction with DRF will always get their 404 details 'swallowed'.
Steps to reproduce
raise Http404('My details') inside of a DRF class-based view or function decorated with api_view
Expected behavior
404 error with message 'My details' is returned
Actual behavior
404 error with message 'Not found' is returned