targhs
targhs

Reputation: 1805

Custom Exceptions with Django Rest Framework

I want to create custom exceptions in DRF. As the DRF documentation states that i can do that by creating a user defined class and inheriting from APIException.

That works well but the issue is my application require me to send some type of custom codes along with the HTTP status codes. For example, when an error occurred while creating a ProductCatalog it should return something like this along with HTTP status code.

{"code": 4026, "message": "Unable to create catalog"}

Such thing is required because although my API worked correctly so the http status code will be 200 but there were some business logic that was not fulfilled hence i need to return some sort of custom code and message to let the client application handle it accordingly.

Any kind of help will be appreciated.

Upvotes: 8

Views: 10643

Answers (2)

targhs
targhs

Reputation: 1805

I figured it out myself. By going through the code i found that if you set default_detail to a dictionary, it will return that as it is.

In my case it would be something like this.

class ProductCatalogExeption(APIException):
    status_code = 200 #or whatever you want
    default_code = '4026'
    #  Custom response below
    default_detail = {"code": 4026, "message": "Unable to create catalog"}

So when ProductCatalogException is raised it will return

{"code": 4026, "message": "Unable to create catalog"}

with HTTP Response code 200

For reference: https://github.com/encode/django-rest-framework/blob/master/rest_framework/exceptions.py

Upvotes: 9

ruddra
ruddra

Reputation: 52028

You can consider creating a custom exception handler, along with a custom exception. Like this:

First create exception handler which will handle errors for DRF:

# custom handler
from rest_framework.views import exception_handler

def custom_exception_handler(exc, context):
    # Call REST framework's default exception handler first,
    # to get the standard error response.
    response = exception_handler(exc, context)

    # Now add the HTTP status code to the response.
    if response is not None:
        response.data['status_code'] = response.default_code

    return response

Then update the settings.py with that error

# settings.py

REST_FRAMEWORK = {
    'EXCEPTION_HANDLER': 'my_project.my_app.utils.custom_exception_handler'
}

Finally, create a custom exception and use that when you need to raise Catalog creation error:

# Custom exception

from rest_framework.exceptions import APIException

class CatalogExeption(APIException):
    status_code = 503
    default_detail = 'Unable to create catalog'
    default_code = '4026'

More information can be found regarding custom exception in documentation.

Upvotes: 5

Related Questions