My Django Rest Framework model views keep throwing Django's html pages to the client even if client sets "Accept: application/json". DRF seems to wrap in JSON only some exceptions by default. How can I prevent returning 30kb html pages (in Debug) if any exceptions occurs? Both in debug and production environments.
-
What does your view code look like? What are your DRF-specific settings? If you set `?format=json` as the query string, do you still get HTML pages back? – Kevin Brown-Silva Apr 05 '15 at 22:21
1 Answers
It sounds like you are talking about the Django error pages that it will generate for you when DEBUG
is set to True
and an unhandled exception is raised. Django REST framework will only handle specific exceptions for you and turn them into formatted responses, you can read more about exception handling in the DRF documentation.
If you are raising these errors yourself, you can change the base exception to be an APIException
, which will then be transformed into a 400 error and formatted to the client. These are the same ones that you will usually see when you get a validation error.
If you are not the one raising these errors, you should look into catching them manually. DRF tries to proactively avoid errors, so if the error is coming because of a DRF call, I would recommend opening a ticket about it. Otherwise, you should be able to wrap it in a standard try...except
block and re-raise the exception as an APIException
so DRF formats it properly.

- 40,873
- 40
- 203
- 237
-
Thank you for pointing at APIException, I read that page several times, but missed that paragraph. However this doesn't solve my problem. What if I want to turn every exception in json? Say I want to type localhost:8000/foobar and get kind of 404 exception instead of default Django page. I have custom error handler, but it is not called (as I can check with debugger and breakpoints). ?format=json also doesn't help. Why does DRF allow Django to throw its pages as is? If I set Debug=True nothing changes except I get concise Django text (again instead of json reply) – Nik Apr 05 '15 at 23:41
-
2DRF [will only intercept](http://www.django-rest-framework.org/api-guide/exceptions/#exception-handling-in-rest-framework-views) `APIException`, [`Http404`](https://docs.djangoproject.com/en/1.8/topics/http/views/#the-http404-exception), and [`PermissionDenied`](http://stackoverflow.com/q/6618939/359284). DRF won't intercept other exceptions because they usually 1) reveal non-public information OR 2) aren't easily serializable. Because these would typically cause a 500 error anyway, DRF forces the developer to fix them by not intercepting them. – Kevin Brown-Silva Apr 06 '15 at 00:17
-
1Thank you, security argument sounds reasonable. However it is not convenient to test api without logging all exceptions (and then reading pile of stack traces): I work on mobile app and if some exception happens, I get bunch of bytes in console, because JSON library can't handle incoming html. As you said, in production Django errors become 500 error, maybe its possible to make it json, not plaintext? And what if 404 exception is not intercepted as I described? I created empty project, added DRF, created `urls.py`, then enter some not existing address, and I see Django 404 page again. – Nik Apr 06 '15 at 01:08