Skip to content

Commit 1befab7

Browse files
Added generic 500 and 400 JSON error handlers. (#5904)
* Added generic 500 and 400 JSON error handlers. * Docs for generic error views.
1 parent 489d341 commit 1befab7

File tree

3 files changed

+68
-2
lines changed

3 files changed

+68
-2
lines changed

Diff for: docs/api-guide/exceptions.md

+28
Original file line numberDiff line numberDiff line change
@@ -230,5 +230,33 @@ The generic views use the `raise_exception=True` flag, which means that you can
230230

231231
By default this exception results in a response with the HTTP status code "400 Bad Request".
232232

233+
234+
---
235+
236+
# Generic Error Views
237+
238+
Django REST Framework provides two error views suitable for providing generic JSON `500` Server Error and
239+
`400` Bad Request responses. (Django's default error views provide HTML responses, which may not be appropriate for an
240+
API-only application.)
241+
242+
Use these as per [Django's Customizing error views documentation][django-custom-error-views].
243+
244+
## `rest_framework.exceptions.server_error`
245+
246+
Returns a response with status code `500` and `application/json` content type.
247+
248+
Set as `handler500`:
249+
250+
handler500 = 'rest_framework.exceptions.server_error'
251+
252+
## `rest_framework.exceptions.server_error`
253+
254+
Returns a response with status code `400` and `application/json` content type.
255+
256+
Set as `handler400`:
257+
258+
handler400 = 'rest_framework.exceptions.bad_request'
259+
233260
[cite]: https://doughellmann.com/blog/2009/06/19/python-exception-handling-techniques/
234261
[authentication]: authentication.md
262+
[django-custom-error-views]: https://docs.djangoproject.com/en/dev/topics/http/views/#customizing-error-views

Diff for: rest_framework/exceptions.py

+21
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import math
1010

11+
from django.http import JsonResponse
1112
from django.utils import six
1213
from django.utils.encoding import force_text
1314
from django.utils.translation import ugettext_lazy as _
@@ -235,3 +236,23 @@ def __init__(self, wait=None, detail=None, code=None):
235236
wait))))
236237
self.wait = wait
237238
super(Throttled, self).__init__(detail, code)
239+
240+
241+
def server_error(request, *args, **kwargs):
242+
"""
243+
Generic 500 error handler.
244+
"""
245+
data = {
246+
'error': 'Server Error (500)'
247+
}
248+
return JsonResponse(data, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
249+
250+
251+
def bad_request(request, exception, *args, **kwargs):
252+
"""
253+
Generic 400 error handler.
254+
"""
255+
data = {
256+
'error': 'Bad Request (400)'
257+
}
258+
return JsonResponse(data, status=status.HTTP_400_BAD_REQUEST)

Diff for: tests/test_exceptions.py

+19-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
# -*- coding: utf-8 -*-
12
from __future__ import unicode_literals
23

3-
from django.test import TestCase
4+
from django.test import RequestFactory, TestCase
45
from django.utils import six, translation
56
from django.utils.translation import ugettext_lazy as _
67

78
from rest_framework.exceptions import (
8-
APIException, ErrorDetail, Throttled, _get_error_details
9+
APIException, ErrorDetail, Throttled, _get_error_details, bad_request,
10+
server_error
911
)
1012

1113

@@ -87,3 +89,18 @@ def test_message(self):
8789
# this test largely acts as a sanity test to ensure the translation files are present.
8890
self.assertEqual(_('A server error occurred.'), 'Une erreur du serveur est survenue.')
8991
self.assertEqual(six.text_type(APIException()), 'Une erreur du serveur est survenue.')
92+
93+
94+
def test_server_error():
95+
request = RequestFactory().get('/')
96+
response = server_error(request)
97+
assert response.status_code == 500
98+
assert response["content-type"] == 'application/json'
99+
100+
101+
def test_bad_request():
102+
request = RequestFactory().get('/')
103+
exception = Exception('Something went wrong — Not used')
104+
response = bad_request(request, exception)
105+
assert response.status_code == 400
106+
assert response["content-type"] == 'application/json'

0 commit comments

Comments
 (0)