Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning JSON error when catching Django exception?

Does anyone have opinions on the best way of having middleware catch exceptions, and instead of rendering the error into a HTML template, to return a JSON object? Currently I have the middleware below that catches exceptions, and if it can find an extra user error message, puts that onto the request (that the template then picks up).

class ExceptionUserErrorMessageMiddleware(object):
    def process_exception(self, request, exception):
        """ if the exception has information relevant to the user, then 
        tack that onto the request object"""

        theFormat = djrequest.get_getvar(request, settings.FORMAT_PARAM, "")
        msg = getMessage(exception)
        if msg:
            setattr(request, USER_ERROR_MESSAGE_ATTR, msg)

        if theFormat == "json":
            print "do something"

What's the best way of returning a json object here? Should I set any additional headers?

Is there a way of doing the same for exceptional circumstances that don't pass through middleware (I'm pretty sure 404 doesn't, are there any others)?

like image 522
Trent Avatar asked Jun 20 '12 22:06

Trent


People also ask

What is JSON response in Django?

Django JsonResponse JsonResponse is an HttpResponse subclass that helps to create a JSON-encoded response. Its default Content-Type header is set to application/json. The first parameter, data , should be a dict instance.

Can Django return JSON?

Django provides a built-in class JsonResponse that makes returning JSON easy. By default, the JsonResponse class sets a Content-Type header of application/json.


1 Answers

What we do on our project MapIt - https://github.com/mysociety/mapit - for doing this is to raise an Exception to a middleware, as you say, which then directly returns either an HTML template or a JSON object depending on the format provided by the request. You can view the code at https://github.com/mysociety/mapit/blob/master/mapit/middleware/view_error.py

In terms of additional headers, our output_json function sets the Content-Type on the response to 'application/json; charset=utf-8'.

For the 404 case, we have our own get_object_or_404 function that wraps get_object_or_404 and converts a Django Http404 exception into our own exception that will then correctly return JSON if appropriate to the request.

from django.shortcuts import get_object_or_404 as orig_get_object_or_404

def get_object_or_404(klass, format='json', *args, **kwargs):
    try:
        return orig_get_object_or_404(klass, *args, **kwargs)
    except http.Http404, e:
        raise ViewException(format, str(e), 404)
like image 79
M Somerville Avatar answered Oct 06 '22 00:10

M Somerville