8

I'm trying to test the exceptions within the django rest framework. Based on http://www.django-rest-framework.org/api-guide/exceptions/ raising NotFound,

By default this exception results in a response with the HTTP status code "404 Not Found".

However when I issue a GET (to /example1) I get a 500 with ,

Request Method: GET Request URL: http://192.168.59.103:8002/example1 Django Version: 1.8.3 Exception Type: NotFound Exception Value: not found Exception Location: /home/djangoapp/testtools/api/views.py in example1, line 7 Python Executable: /usr/bin/python 

details below,

settings.py

REST_FRAMEWORK = {'EXCEPTION_HANDLER':'rest_framework.views.exception_handler'} INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', ) 

urls.py

from django.conf.urls import include, url from api import views urlpatterns = [ url(r'example1', views.example1), ] 

views.py

from rest_framework import status from rest_framework.decorators import api_view from rest_framework.response import Response from rest_framework.exceptions import APIException,ParseError,NotFound def example1(request): raise NotFound("not found") 

Any ideas ?

1
  • In your comments to @ArpitGoyal's answer you say you actually want to know how to generate your own 404 response for any URL not just this sample code. can you please clarify the question if that's true? Commented Aug 8, 2015 at 23:56

3 Answers 3

16
+150
from rest_framework.exceptions import NotFound 

The class NotFound is extended from APIException. The default status code for APIException is 500 Internal Server Error, whereas for NotFound is 404.

So according to me here you are trying to throw a rest framework exception in a pure django view. I wrote a test case here to check what are the odds of getting the error raised. Guess what a simple django view trying to raise a rest framework exception is not recognized as an error to the view. But on providing the decorator and declaring it an API View it enters the exception_handler

So when you do:

from rest_framework.decorators import api_view @api_view() def example1(request): raise NotFound('not found') 

This is now recognized as an exception thrown by the API which enters the default rest_framework EXCEPTION_HANDLER provided by you, where it returns the response for any given exception.

Its docstring says:

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 ValidationError, Http404 and PermissionDenied exceptions. Any unhandled exceptions may return None, which will cause a 500 error to be raised.

Sign up to request clarification or add additional context in comments.

8 Comments

Ok cool. Makes sense. Also If i then throw a request for /example2 should this not raise the NotFound by the DRF without the need for me to configure anything else.
The behaviour should be same for every url if the code remains the same.
ok, i must be missing something as cant get it to auto generate the 404 JSON response
Any ideas. your answer answers 90% of the question its just the last bit.
I didn't get you. The only thing here I can think off is that only. The NotFound is an api exception and you can raise it as an error only on an APIView. In a pure django view it is recognised as an internal server error. What did you mean with the last part?
|
2

I'm not sure why you are doing this. That's an internal exception used by DRF when it can't find a resource. But you're using it in a standard Django view, outside any of the DRF machinery. If you want to do that, you should use the standard Django exception:

from django.core.exceptions import Http404 def example1(request): raise Http404('not found') 

Comments

1

Try to change your url with a reqular expression which matches all possible urls and place it at the end of the main urls.py

for ex:

urlpatterns = [ url(r'^(?P<slug>[\w-]+)/', views.example1), ] 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.