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 warnings
from django.core.exceptions import ValidationError as DjangoValidationError
from django.core.exceptions import PermissionDenied
from django.http import Http404
from django.utils import six
@ -90,6 +91,12 @@ def exception_handler(exc, context):
set_rollback()
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.
return None

View File

@ -3,6 +3,7 @@ from __future__ import unicode_literals
import copy
import sys
from django.core.validators import validate_ipv4_address
from django.test import TestCase
from rest_framework import status
@ -19,6 +20,8 @@ if sys.version_info[:2] >= (3, 4):
else:
JSON_ERROR = 'JSON parse error - No JSON object could be decoded'
IPV4_VALIDATION_ERROR = ['Enter a valid IPv4 address.']
class BasicView(APIView):
def get(self, request, *args, **kwargs):
@ -50,6 +53,18 @@ def error_view(request):
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):
"""
Exact contents of JSON error messages depend on the installed version
@ -148,3 +163,27 @@ class TestCustomExceptionHandler(TestCase):
expected = 'Error!'
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
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)