Skip to content

Commit 1fb4e0b

Browse files
committed
Avoid calling get_serializer during error handling
1 parent e9ca8d9 commit 1fb4e0b

File tree

3 files changed

+39
-3
lines changed

3 files changed

+39
-3
lines changed

example/tests/__snapshots__/test_errors.ambr

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,17 @@
6161
],
6262
}
6363
---
64+
# name: test_404_during_serializer_context
65+
<class 'dict'> {
66+
'errors': <class 'list'> [
67+
<class 'dict'> {
68+
'code': 'not_found',
69+
'detail': 'Not found.',
70+
'status': '404',
71+
},
72+
],
73+
}
74+
---
6475
# name: test_second_level_array_error
6576
<class 'dict'> {
6677
'errors': <class 'list'> [

example/tests/test_errors.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import pytest
2+
from django.http import Http404
23
from django.test import override_settings
34
from django.urls import path, reverse
45
from rest_framework import generics
@@ -48,7 +49,10 @@ class DummyTestView(generics.CreateAPIView):
4849
resource_name = "entries"
4950

5051
def get_serializer_context(self):
51-
return {}
52+
if self.request.GET.get("fail"):
53+
raise Http404
54+
else:
55+
return {}
5256

5357

5458
urlpatterns = [
@@ -211,3 +215,20 @@ def test_relationship_errors_has_correct_pointers(client, some_blog, snapshot):
211215
}
212216

213217
assert snapshot == perform_error_test(client, data)
218+
219+
220+
def test_404_during_serializer_context(client, some_blog, snapshot):
221+
data = {
222+
"data": {
223+
"type": "entries",
224+
"attributes": {
225+
"blog": some_blog.pk,
226+
"bodyText": "body_text",
227+
},
228+
}
229+
}
230+
with override_settings(ROOT_URLCONF=__name__):
231+
url = reverse("entries-nested-list")
232+
response = client.post(f"{url}?fail=1", data=data)
233+
234+
assert snapshot == response.json()

rest_framework_json_api/utils.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,8 +377,12 @@ def format_drf_errors(response, context, exc):
377377

378378
has_serializer = isinstance(context["view"], generics.GenericAPIView)
379379
if has_serializer:
380-
serializer = context["view"].get_serializer()
381-
fields = get_serializer_fields(serializer) or dict()
380+
try:
381+
serializer_class = context["view"].get_serializer_class()
382+
serializer = serializer_class()
383+
fields = get_serializer_fields(serializer) or dict()
384+
except Exception:
385+
fields = []
382386
relationship_fields = [
383387
name for name, field in fields.items() if is_relationship_field(field)
384388
]

0 commit comments

Comments
 (0)