Handle more edge cases.

Signed-off-by: James Tanner <tanner.jc@gmail.com>
This commit is contained in:
James Tanner 2024-03-19 18:05:10 -04:00
parent 1353bfa236
commit 586c0444aa
No known key found for this signature in database
GPG Key ID: EB4645E850012701
2 changed files with 57 additions and 3 deletions

View File

@ -177,9 +177,7 @@ class ValidationError(APIException):
"""Handle error messages with templates and placeholders."""
try:
return detail % params
except KeyError:
return detail
except ValueError:
except (KeyError, ValueError, TypeError, IndexError, AttributeError):
return detail

View File

@ -214,6 +214,22 @@ class TestValidationErrorWithDjangoStyle(TestCase):
with pytest.raises(ValidationError):
raise ValidationError(errors)
def test_validation_error_without_params_digit(self):
"""Ensure that substitutable errors can be emitted with a digit placeholder."""
# mimic the logic in fields.Field.run_validators by saving the exception
# detail into a list which will then be the detail for a new ValidationError.
# this should not throw a TypeError on the date format placeholders ...
errors = []
try:
raise ValidationError(detail='%d')
except ValidationError as exc:
errors.extend(exc.detail)
# ensure it raises the correct exception type as an input to a new ValidationError
with pytest.raises(ValidationError):
raise ValidationError(errors)
def test_validation_error_without_params_date_formatters(self):
"""Ensure that substitutable errors can be emitted with invalid template placeholders."""
@ -229,3 +245,43 @@ class TestValidationErrorWithDjangoStyle(TestCase):
# ensure it raises the correct exception type as an input to a new ValidationError
with pytest.raises(ValidationError):
raise ValidationError(errors)
def test_validation_error_with_param_that_has_attribute_error(self):
"""Ensure that substitutable errors can be emitted with a bad string repr."""
class FooBar:
def __str__(self):
raise AttributeError("i was poorly coded")
# mimic the logic in fields.Field.run_validators by saving the exception
# detail into a list which will then be the detail for a new ValidationError.
# this should not throw a ValueError on the date format placeholders ...
errors = []
try:
raise ValidationError(detail='%s', params=FooBar())
except ValidationError as exc:
errors.extend(exc.detail)
# ensure it raises the correct exception type as an input to a new ValidationError
with pytest.raises(ValidationError):
raise ValidationError(errors)
def test_validation_error_with_param_that_has_index_error(self):
"""Ensure that substitutable errors can be emitted with a bad string repr."""
class FooBar:
def __str__(self):
raise IndexError("i was poorly coded")
# mimic the logic in fields.Field.run_validators by saving the exception
# detail into a list which will then be the detail for a new ValidationError.
# this should not throw a ValueError on the date format placeholders ...
errors = []
try:
raise ValidationError(detail='%s', params=FooBar())
except ValidationError as exc:
errors.extend(exc.detail)
# ensure it raises the correct exception type as an input to a new ValidationError
with pytest.raises(ValidationError):
raise ValidationError(errors)