Skip to content

Commit

Permalink
get_error_detail: use error_dict/error_list
Browse files Browse the repository at this point in the history
  • Loading branch information
blueyed committed Jun 19, 2018
1 parent 3fcc076 commit d9ee7d6
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 5 deletions.
19 changes: 15 additions & 4 deletions rest_framework/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,10 +233,21 @@ def get_error_detail(exc_info):
with the `code` populated.
"""
code = getattr(exc_info, 'code', None) or 'invalid'
return [
ErrorDetail(msg, code=code)
for msg in exc_info.messages
]

try:
error_dict = exc_info.error_dict
except AttributeError:
return [
ErrorDetail(error.message % (error.params or ()),
code=error.code if error.code else code)
for error in exc_info.error_list]
return {
k: [
ErrorDetail(error.message % (error.params or ()),
code=error.code if error.code else code)
for error in errors
] for k, errors in error_dict.items()
}


class CreateOnlyDefault(object):
Expand Down
91 changes: 90 additions & 1 deletion tests/test_fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
from decimal import ROUND_DOWN, ROUND_UP, Decimal

import pytest
from django.core.exceptions import ValidationError as DjangoValidationError
from django.http import QueryDict
from django.test import TestCase, override_settings
from django.utils import six
from django.utils.timezone import activate, deactivate, override, utc

import rest_framework
from rest_framework import compat, serializers
from rest_framework import compat, exceptions, serializers
from rest_framework.fields import DjangoImageField, is_simple_callable

try:
Expand Down Expand Up @@ -2183,3 +2184,91 @@ class ExampleSerializer(serializers.Serializer):
"'ExampleSerializer', because it is the same as the default "
"method name. Remove the `method_name` argument."
)


class TestValidationErrorCode:
@pytest.mark.parametrize('use_list', (False, True))
def test_validationerror_code_with_msg(self, use_list):

class ExampleSerializer(serializers.Serializer):
password = serializers.CharField()

def validate_password(self, obj):
err = DjangoValidationError('exc_msg', code='exc_code')
if use_list:
err = DjangoValidationError([err])
raise err

serializer = ExampleSerializer(data={'password': 123})
serializer.is_valid()
assert serializer.errors == {'password': ['exc_msg']}
assert serializer.errors['password'][0].code == 'exc_code'

@pytest.mark.parametrize('code', (None, 'exc_code',))
@pytest.mark.parametrize('use_list', (False, True))
def test_validationerror_code_with_dict(self, use_list, code):

class ExampleSerializer(serializers.Serializer):

def validate(self, obj):
if code is None:
err = DjangoValidationError({
'email': 'email error',
})
else:
err = DjangoValidationError({
'email': DjangoValidationError(
'email error',
code=code),
})
if use_list:
err = DjangoValidationError([err])
raise err

serializer = ExampleSerializer(data={})
serializer.is_valid()
expected_code = code if code else 'invalid'
if use_list:
assert serializer.errors == {
'non_field_errors': [
exceptions.ErrorDetail(
string='email error',
code=expected_code
)
]
}
else:
assert serializer.errors == {
'email': ['email error'],
}
assert serializer.errors['email'][0].code == expected_code

@pytest.mark.parametrize('code', (None, 'exc_code',))
def test_validationerror_code_with_dict_list_same_code(self, code):

class ExampleSerializer(serializers.Serializer):

def validate(self, obj):
if code is None:
raise DjangoValidationError({'email': ['email error 1',
'email error 2']})
raise DjangoValidationError({'email': [
DjangoValidationError('email error 1', code=code),
DjangoValidationError('email error 2', code=code),
]})

serializer = ExampleSerializer(data={})
serializer.is_valid()
expected_code = code if code else 'invalid'
assert serializer.errors == {
'email': [
exceptions.ErrorDetail(
string='email error 1',
code=expected_code
),
exceptions.ErrorDetail(
string='email error 2',
code=expected_code
),
]
}

0 comments on commit d9ee7d6

Please sign in to comment.