Skip to content

Commit b840ae1

Browse files
committed
Avoided shadowing of exception when rendering errors
1 parent 2568417 commit b840ae1

File tree

3 files changed

+19
-6
lines changed

3 files changed

+19
-6
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ any parts of the framework not mentioned in the documentation should generally b
2222
* `ModelSerializer` fields are now returned in the same order than DRF
2323
* Avoided that an empty attributes dict is rendered in case serializer does not
2424
provide any attribute fields.
25+
* Avoided shadowing of exception when rendering errors (regression since 4.3.0).
2526

2627
### Removed
2728

rest_framework_json_api/utils.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -381,18 +381,19 @@ def format_drf_errors(response, context, exc):
381381
errors.extend(format_error_object(message, "/data", response))
382382
# handle all errors thrown from serializers
383383
else:
384-
# Avoid circular deps
385-
from rest_framework import generics
386-
387-
has_serializer = isinstance(context["view"], generics.GenericAPIView)
388-
if has_serializer:
384+
try:
389385
serializer = context["view"].get_serializer()
390386
fields = get_serializer_fields(serializer) or dict()
391387
relationship_fields = [
392388
format_field_name(name)
393389
for name, field in fields.items()
394390
if is_relationship_field(field)
395391
]
392+
except Exception:
393+
# ignore potential errors when retrieving serializer
394+
# as it might shadow error which is currently being
395+
# formatted
396+
serializer = None
396397

397398
for field, error in response.data.items():
398399
non_field_error = field == api_settings.NON_FIELD_ERRORS_KEY
@@ -401,7 +402,7 @@ def format_drf_errors(response, context, exc):
401402
if non_field_error:
402403
# Serializer error does not refer to a specific field.
403404
pointer = "/data"
404-
elif has_serializer:
405+
elif serializer:
405406
# pointer can be determined only if there's a serializer.
406407
rel = "relationships" if field in relationship_fields else "attributes"
407408
pointer = f"/data/{rel}/{field}"

tests/test_views.py

+11
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,17 @@ def test_list_with_include_nested_related_field(
154154
"included"
155155
]
156156

157+
@pytest.mark.urls(__name__)
158+
def test_list_with_invalid_include(self, client, foreign_key_source):
159+
url = reverse("foreign-key-source-list")
160+
response = client.get(url, data={"include": "invalid"})
161+
assert response.status_code == status.HTTP_400_BAD_REQUEST
162+
result = response.json()
163+
assert (
164+
result["errors"][0]["detail"]
165+
== "This endpoint does not support the include parameter for path invalid"
166+
)
167+
157168
@pytest.mark.urls(__name__)
158169
def test_list_with_default_included_resources(self, client, foreign_key_source):
159170
url = reverse("default-included-resources-list")

0 commit comments

Comments
 (0)