0

I am developing Restful API using Django.

In case of an error instead of raising python default exception or adding try except on every view, is there a way to add a default error message which will be returned?

via django settings? via the url's? via a decoretor?

thanx in advanced :)

Oz

Oz Cohen
  • 873
  • 1
  • 8
  • 11
  • Does this answer your question? [Global Exception Handling in Django-rest-framework](https://stackoverflow.com/questions/60426446/global-exception-handling-in-django-rest-framework) – Ankit Tiwari Aug 15 '22 at 14:08

1 Answers1

1

Considering you use DRF you can define your own exception handler:

def custom_api_exception_handler(exc, ctx):
    if isinstance(exc, DjangoValidationError):
        exc = exceptions.ValidationError(as_serializer_error(exc))

    if isinstance(exc, Http404):
        exc = exceptions.NotFound()

    if isinstance(exc, PermissionDenied):
        exc = exceptions.PermissionDenied()

    response = exception_handler(exc, ctx)

    # If unexpected error occurs (server error, etc.)
    if response is None:
        if isinstance(exc, YourCustomApplicationError):
            data = {"message": exc.message, "extra": exc.extra}
            return Response(data, status=400)

        return response

    if isinstance(exc.detail, (list, dict)):
        response.data = {"detail": response.data}

    if isinstance(exc, exceptions.ValidationError):
        response.data["message"] = "Validation error"
        response.data["extra"] = {"fields": response.data["detail"]}
    else:
        response.data["message"] = response.data["detail"]
        response.data["extra"] = {}

    del response.data["detail"]

    return response

and define your custom exception:

class YourCustomApplicationError(Exception):
  def __init__(self, message, extra=None):
    super().__init__(message)
    
    self.message = message
    self.extra = extra or {}

The example above has the following format, however, you can customize it to your needs.

    {
        "message": "Error message",
        "extra": {}
    }

In order to use your custom exception handler in APIs, in settings.py add the custom exception handler to the DRF settings:

REST_FRAMEWORK = {
  "EXCEPTION_HANDLER": "path-to-custom-exception-handler.custom_api_exception_handler",
  ... 
}

Documentation: https://www.django-rest-framework.org/api-guide/exceptions/#custom-exception-handling

EDIT: Forgot to mention that you can also use your custom exception in services for validation, etc.

if some_condition:
  raise YourCustomApplicationError(msg)
antpngl92
  • 494
  • 4
  • 12