add default handling of Django ValidationError exceptions

This commit is contained in:
Rock Howard 2015-07-14 13:20:57 -05:00
parent 6b08e97b6a
commit 413fe93dbf
2 changed files with 46 additions and 0 deletions

View File

@ -6,6 +6,7 @@ from __future__ import unicode_literals
import inspect import inspect
import warnings import warnings
from django.core.exceptions import ValidationError as DjangoValidationError
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.http import Http404 from django.http import Http404
from django.utils import six from django.utils import six
@ -90,6 +91,12 @@ def exception_handler(exc, context):
set_rollback() set_rollback()
return Response(data, status=status.HTTP_403_FORBIDDEN) return Response(data, status=status.HTTP_403_FORBIDDEN)
elif isinstance(exc, DjangoValidationError):
msg = _('Validation error.')
data = {'detail': exc.messages}
set_rollback()
return Response(data, status=status.HTTP_400_BAD_REQUEST)
# Note: Unhandled exceptions will raise a 500 error. # Note: Unhandled exceptions will raise a 500 error.
return None return None

View File

@ -3,6 +3,7 @@ from __future__ import unicode_literals
import copy import copy
import sys import sys
from django.core.validators import validate_ipv4_address
from django.test import TestCase from django.test import TestCase
from rest_framework import status from rest_framework import status
@ -19,6 +20,8 @@ if sys.version_info[:2] >= (3, 4):
else: else:
JSON_ERROR = 'JSON parse error - No JSON object could be decoded' JSON_ERROR = 'JSON parse error - No JSON object could be decoded'
IPV4_VALIDATION_ERROR = ['Enter a valid IPv4 address.']
class BasicView(APIView): class BasicView(APIView):
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
@ -50,6 +53,18 @@ def error_view(request):
raise Exception raise Exception
class ValidationErrorView(APIView):
def get(self, request, *args, **kwargs):
'raises a django ValidtionError by calling the ip4 validation function with a bad input'
validate_ipv4_address('a.b.c.d')
@api_view(['GET'])
def validation_error_view(request):
'raises a django ValidtionError by calling the ip4 validation function with a bad input'
validate_ipv4_address('a.b.c.d')
def sanitise_json_error(error_dict): def sanitise_json_error(error_dict):
""" """
Exact contents of JSON error messages depend on the installed version Exact contents of JSON error messages depend on the installed version
@ -148,3 +163,27 @@ class TestCustomExceptionHandler(TestCase):
expected = 'Error!' expected = 'Error!'
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.data, expected) self.assertEqual(response.data, expected)
class TestDjangoValidationErrorHandlling(TestCase):
def test_class_based_validation_error_handling(self):
view = ValidationErrorView.as_view()
request = factory.get('/')
response = view(request)
expected = {
'detail': IPV4_VALIDATION_ERROR
}
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.data, expected)
def test_function_based_validation_error_handling(self):
view = validation_error_view
request = factory.get('/')
response = view(request)
expected = {
'detail': IPV4_VALIDATION_ERROR
}
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertEqual(response.data, expected)