Coverage for jutil/drf_exceptions.py: 46%
25 statements
« prev ^ index » next coverage.py v6.5.0, created at 2022-10-07 16:40 -0500
« prev ^ index » next coverage.py v6.5.0, created at 2022-10-07 16:40 -0500
1import logging
2from typing import Any
3from django.core.exceptions import ValidationError as DjangoValidationError
5try:
6 from rest_framework.exceptions import ValidationError as DRFValidationError # type: ignore
7 from rest_framework.views import exception_handler as drf_exception_handler # type: ignore
8except Exception as err:
9 raise Exception("Using jutil.drf_exceptions requires djangorestframework installed") from err
11logger = logging.getLogger(__name__)
14def transform_exception_to_drf(exception: Exception) -> Exception:
15 """
16 Transform Django ValidationError into an equivalent DRF ValidationError.
17 Note that even if this approach is not technically recommended, this is still
18 the most convenient way to handle shared validation between Django admin and API.
19 """
20 if isinstance(exception, DjangoValidationError): 20 ↛ 31line 20 didn't jump to line 31, because the condition on line 20 was never false
21 detail: Any = str(exception)
22 if hasattr(exception, "message_dict"): 22 ↛ 24line 22 didn't jump to line 24, because the condition on line 22 was never false
23 detail = exception.message_dict
24 elif hasattr(exception, "messages"):
25 detail = exception.messages
26 elif hasattr(exception, "message"):
27 detail = exception.message
28 else:
29 logger.error("Unsupported ValidationError detail: %s", exception)
30 return DRFValidationError(detail=detail)
31 return exception
34def custom_exception_handler(exc, context):
35 """
36 Custom DRF exception handler which converts Django ValidationError to DRF ValidationError.
37 Note that even if this approach is not technically recommended, this is still
38 the most convenient way to handle shared validation between Django admin and API.
40 DRF exception handler must be set in settings.py:
42 REST_FRAMEWORK = {
43 ... # ...
44 ... 'EXCEPTION_HANDLER': 'jutil.drf_exceptions.custom_exception_handler',
45 ... # ...
46 ... }
47 """
48 if isinstance(exc, DjangoValidationError):
49 exc = transform_exception_to_drf(exc)
50 return drf_exception_handler(exc, context)