Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add custom error codes to Django Rest Framework

I am putting together an API with Django Rest Framework. I want to customise my error handling. I read quite a bit (link1, link2, link3) about custom error handling but can't find something that suits my needs.

Basically, I'd like to change the structure of my error messages to get something like this :

{
  "error": True,
  "errors": [
    {
      "message": "Field %s does not exist",
      "code": 1050
    }
  ]
}

Instead of :

{"detail":"Field does not exist"}

I already have a custom ExceptionMiddleware to catch the 500 errors and return a JSON, but I have no power on all the other errors.

Code of the ExceptionMiddleware:

class ExceptionMiddleware(object):

    def process_exception(self, request, exception):

        if request.user.is_staff:
            detail = exception.message
        else:
            detail = 'Something went wrong, please contact a staff member.'

        return HttpResponse('{"detail":"%s"}'%detail, content_type="application/json", status=500)

From Django doc :

Note that the exception handler will only be called for responses generated by raised exceptions. It will not be used for any responses returned directly by the view, such as the HTTP_400_BAD_REQUEST responses that are returned by the generic views when serializer validation fails.

This is exactly what I am trying to achieve, customise those 400 errors.

Thanks a lot,

like image 656
user1800356 Avatar asked Feb 17 '16 12:02

user1800356


1 Answers

I know this is a bit late, (better late than never).

If you have a structured error message, then try this by inheriting the Exception class

from rest_framework.serializers import ValidationError
from rest_framework import status


class CustomAPIException(ValidationError):
    status_code = status.HTTP_400_BAD_REQUEST
    default_code = 'error'

    def __init__(self, detail, status_code=None):
        self.detail = detail
        if status_code is not None:
            self.status_code = status_code

and the usage will be like this:

if some_condition:
    error_msg = {
        "error": True,
        "errors": [
            {
                "message": "Field %s does not exist"%('my_test_field'),
                "code": 1050
            }
        ]
    }
    raise CustomAPIException(error_msg)

Reference : How to override exception messages in django rest framework

like image 88
JPG Avatar answered Sep 22 '22 20:09

JPG