Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions src/dso_api/dynamic_api/views/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ class (namely the :class:`~dso_api.dynamic_api.views.DynamicApiViewSet` base cla
from functools import cached_property

from django.db import models
from django.db.utils import ProgrammingError
from django.db.utils import DatabaseError, InternalError, ProgrammingError
from django.utils.decorators import method_decorator
from django.utils.translation import gettext as _
from django.views.decorators.cache import never_cache
from rest_framework import viewsets
from rest_framework.exceptions import NotFound, PermissionDenied
from rest_framework.exceptions import NotFound, PermissionDenied, ValidationError
from schematools.contrib.django.models import DynamicModel

from dso_api.dynamic_api import filters, permissions, serializers
Expand Down Expand Up @@ -70,7 +70,7 @@ class DynamicApiViewSet(NestedViewSetMixin, DSOViewMixin, viewsets.ReadOnlyModel
def list(self, request, *args, **kwargs):
try:
return super().list(request, *args, **kwargs)
except ProgrammingError as e:
except (ProgrammingError, InternalError) as e:
self._handle_db_error(e)
raise

Expand All @@ -81,11 +81,12 @@ def retrieve(self, request, *args, **kwargs):
self._handle_db_error(e)
raise

def _handle_db_error(self, e: ProgrammingError) -> None:
"""Make sure database permission errors are gratefully handled.
This is a common source of 500 error issues,
and giving a better response to the user helps.
def _handle_db_error(self, e: DatabaseError) -> None:
"""Make sure database permission errors and invalid coordinate
errors are gratefully handled. These are a common source of
500 error issues, and giving a better response to the user helps.
"""

if str(e).startswith("permission denied for "):
logger.exception("Database role has no access (while application allowed): %s", e)
raise PermissionDenied(
Expand All @@ -94,6 +95,14 @@ def _handle_db_error(self, e: ProgrammingError) -> None:
code="db_permission_denied",
) from e

if str(e).startswith("transform"):
logger.warning("Invalid CRS transform requested: %s", e)
raise ValidationError(
"Invalid coordinate reference system or transform."
"You may want to add an Accept-Crs header.",
code="invalid_crs",
) from e

def initial(self, request, *args, **kwargs):
super().initial(request, *args, **kwargs)
table_schema = self.model.table_schema()
Expand Down
43 changes: 43 additions & 0 deletions src/tests/test_dynamic_api/views/test_api_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,49 @@ def test_syntax_error(param, api_client, afval_dataset, filled_router):
reason = response.data["invalid-params"][0]["reason"]
assert param in reason

@staticmethod
def test_transform_crs_without_header(
api_client,
parkeervakken_dataset,
filled_router,
):
response = api_client.get(
"/v1/parkeervakken/parkeervakken/?geometry[intersects]="
"POLYGON((119814 485931,"
"121814 485931,"
"121814 487931,"
"119814 487931,"
"119814 485931))",
)
data = read_response_json(response)
assert response.status_code == 400, data
assert response.data["invalid-params"] == [
{
"type": "urn:apiexception:invalid:invalid_crs",
"name": "invalid_crs",
"reason": "Invalid coordinate reference system or transform.You may want to add "
"an Accept-Crs header.",
}
]

@staticmethod
def test_transform_crs_with_header(
api_client,
parkeervakken_dataset,
filled_router,
):
response = api_client.get(
"/v1/parkeervakken/parkeervakken/?geometry[intersects]="
"POLYGON((119814 485931,"
"121814 485931,"
"121814 487931,"
"119814 487931,"
"119814 485931))",
headers={"Accept-Crs": "EPSG:28992"},
)
data = read_response_json(response)
assert response.status_code == 200, data


@pytest.mark.django_db
class TestFilterFieldTypes:
Expand Down
Loading