From b840ae155dc1f5b1899f6d0cf121afb58c51633d Mon Sep 17 00:00:00 2001 From: Oliver Sauder Date: Thu, 18 Apr 2024 21:42:53 +0200 Subject: [PATCH] Avoided shadowing of exception when rendering errors --- CHANGELOG.md | 1 + rest_framework_json_api/utils.py | 13 +++++++------ tests/test_views.py | 11 +++++++++++ 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 964f6b16..0b05600b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ any parts of the framework not mentioned in the documentation should generally b * `ModelSerializer` fields are now returned in the same order than DRF * Avoided that an empty attributes dict is rendered in case serializer does not provide any attribute fields. +* Avoided shadowing of exception when rendering errors (regression since 4.3.0). ### Removed diff --git a/rest_framework_json_api/utils.py b/rest_framework_json_api/utils.py index 2e57fbbd..e12080ac 100644 --- a/rest_framework_json_api/utils.py +++ b/rest_framework_json_api/utils.py @@ -381,11 +381,7 @@ def format_drf_errors(response, context, exc): errors.extend(format_error_object(message, "/data", response)) # handle all errors thrown from serializers else: - # Avoid circular deps - from rest_framework import generics - - has_serializer = isinstance(context["view"], generics.GenericAPIView) - if has_serializer: + try: serializer = context["view"].get_serializer() fields = get_serializer_fields(serializer) or dict() relationship_fields = [ @@ -393,6 +389,11 @@ def format_drf_errors(response, context, exc): for name, field in fields.items() if is_relationship_field(field) ] + except Exception: + # ignore potential errors when retrieving serializer + # as it might shadow error which is currently being + # formatted + serializer = None for field, error in response.data.items(): non_field_error = field == api_settings.NON_FIELD_ERRORS_KEY @@ -401,7 +402,7 @@ def format_drf_errors(response, context, exc): if non_field_error: # Serializer error does not refer to a specific field. pointer = "/data" - elif has_serializer: + elif serializer: # pointer can be determined only if there's a serializer. rel = "relationships" if field in relationship_fields else "attributes" pointer = f"/data/{rel}/{field}" diff --git a/tests/test_views.py b/tests/test_views.py index de5d1b7a..acba7e66 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -154,6 +154,17 @@ def test_list_with_include_nested_related_field( "included" ] + @pytest.mark.urls(__name__) + def test_list_with_invalid_include(self, client, foreign_key_source): + url = reverse("foreign-key-source-list") + response = client.get(url, data={"include": "invalid"}) + assert response.status_code == status.HTTP_400_BAD_REQUEST + result = response.json() + assert ( + result["errors"][0]["detail"] + == "This endpoint does not support the include parameter for path invalid" + ) + @pytest.mark.urls(__name__) def test_list_with_default_included_resources(self, client, foreign_key_source): url = reverse("default-included-resources-list") pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy