Skip to content Skip to sidebar Skip to footer

Django Rest Framework - Best Way To Deal With Api Parameter Validation Errors?

What would be an efficient way to construct error messages during HTTP request parameter validation and serialize them? Currently, as I have it: except Section.DoesNotExist:

Solution 1:

Django REST framework handles errors internally and in general does a pretty good job of converting them into reasonable responses that can be parsed by clients. This is done by the internal exception handling, which is open to being extended for special cases.

Usually when you run into a case where an object was specified that does not exist, you raise a 404 Not Found error. Django actually has a helper for this, called get_object_or_404, as it tends to be a very common bit of logic, especially in APIs. Django REST framework will convert this Http404 error that is raised and convert it in to the following response that has a 404 HTTP error code.

{"detail":"Not found"}

Now, this format (and object with a detail key) is not restricted to only Http404 errors, it works for any error that subclasses APIError provided by Django REST framework.

So in your example, you could raise a similar exception by doing

ex = APIError("Section not found")
ex.status_code = 404

raise ex

Or by using get_object_or_404 and letting Django REST framework handle it

from django.shortcuts importget_object_or_404section= get_object_or_404(Section.objects, pk=1234)

Of course, you can still override the exception handler to format these errors how you want.

def exception_handler(exc):
    from django.http import Http404
    from rest_framework import status

    exc_data = {
        "errors": [],
    }

    if isinstance(exc, Http404):
        exc_data["errors"].append({
            "message": "Sorry that page does not exist",
            "code": 404,
        })
    else if isinstance(exc.detail, list):
        for message in exc.detail:
            exc_data["errors"].append({
                "message": message,
                "code": exc.status_code,
            }
    else:
        exc_data["errors"].append({
            "message": exc.detail,
            "code": exc.status_code,
        })

    return Response(exc_data, status=status.HTTP_200_OK)

Note that this will give all error responses a status code of 200, and embed the actual HTTP status code within the body. This is useful for some applications, but it is usually recommended to only use the 200 status code for success responses.

Post a Comment for "Django Rest Framework - Best Way To Deal With Api Parameter Validation Errors?"