mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-30 05:24:00 +03:00
Merge pull request #2608 from ezheidtmann/dont-swallow-errors-in-callable-sources
Dont swallow errors in callable sources
This commit is contained in:
commit
cda74b5997
|
@ -71,7 +71,14 @@ def get_attribute(instance, attrs):
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
return None
|
return None
|
||||||
if is_simple_callable(instance):
|
if is_simple_callable(instance):
|
||||||
|
try:
|
||||||
instance = instance()
|
instance = instance()
|
||||||
|
except (AttributeError, KeyError) as exc:
|
||||||
|
# If we raised an Attribute or KeyError here it'd get treated
|
||||||
|
# as an omitted field in `Field.get_attribute()`. Instead we
|
||||||
|
# raise a ValueError to ensure the exception is not masked.
|
||||||
|
raise ValueError('Exception raised in callable attribute "{0}"; original exception was: {1}'.format(attr, exc))
|
||||||
|
|
||||||
return instance
|
return instance
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -93,6 +93,31 @@ class TestSource:
|
||||||
"same as the field name. Remove the `source` keyword argument."
|
"same as the field name. Remove the `source` keyword argument."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def test_callable_source(self):
|
||||||
|
class ExampleSerializer(serializers.Serializer):
|
||||||
|
example_field = serializers.CharField(source='example_callable')
|
||||||
|
|
||||||
|
class ExampleInstance(object):
|
||||||
|
def example_callable(self):
|
||||||
|
return 'example callable value'
|
||||||
|
|
||||||
|
serializer = ExampleSerializer(ExampleInstance())
|
||||||
|
assert serializer.data['example_field'] == 'example callable value'
|
||||||
|
|
||||||
|
def test_callable_source_raises(self):
|
||||||
|
class ExampleSerializer(serializers.Serializer):
|
||||||
|
example_field = serializers.CharField(source='example_callable', read_only=True)
|
||||||
|
|
||||||
|
class ExampleInstance(object):
|
||||||
|
def example_callable(self):
|
||||||
|
raise AttributeError('method call failed')
|
||||||
|
|
||||||
|
with pytest.raises(ValueError) as exc_info:
|
||||||
|
serializer = ExampleSerializer(ExampleInstance())
|
||||||
|
serializer.data.items()
|
||||||
|
|
||||||
|
assert 'method call failed' in str(exc_info.value)
|
||||||
|
|
||||||
|
|
||||||
class TestReadOnly:
|
class TestReadOnly:
|
||||||
def setup(self):
|
def setup(self):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user