max max - 5 months ago 42
Ajax Question

how to send a failure response from django to ajax

I have this Ajax request:

$.ajax({
url: "my_url",
headers: {'X-CSRFToken': '{{ csrf_token }}'},
type: "post",
data:{x:1
},
success: function(response, textStatus, xhr) {
alert(response + textStatus + xhr);

},
error: function(xhr, ajaxOptions, thrownError) {
alert(xhr.status + ' Error: ' + thrownError);
}
});

}


on the Django side, I sometimes want to propagate errors.
If I raise an exception, it will propagate as a 500 response INTERNAL ERORR.
But I want to display an error message.
so I tried

return HttpResponse("Bad permissions", status=500)


but I'm not able to capture the custom error message.
Any ideas?




For those of you how want to know what worked:

// javascript in the template
function send(){
$.ajax({
url: "/get_pens/",
headers: {'X-CSRFToken': '{{ csrf_token }}'},
type: "post",
data:{x:1
},
dataType: "json",
success: function(response, textStatus, xhr) {
alert('Success: ' + response + textStatus + xhr);

},
error: function(xhr, ajaxOptions, thrownError) {
alert(xhr.status + ' Error: ' + xhr.responseJSON['err']);
}
});
}
// views.py
def get_pens(request):
pens = []
response = HttpResponse(json.dumps({'pens': pens, 'err': 'some custom error message'}),
content_type='application/json')
response.status_code = 400
return response

Answer

One way you can approach this is as following,

You have proper try exception blocks around the code around the block which are prone to raise exceptions. There are lot many Exception subclasses which can cover the type of the exception being raised for eg. Model.DoesNotExist. In those exception blocks, you simply create appropriate HttpResponse and send it back. Lets take an example here.

class DemoView(View):
    def post(self, request, oid, *args, **kwargs):
    try:
        object = Model.objects.get(id=oid)
    except Model.DoesNotExist:
        return HttpResponseNotFound('error message')

This way your error block is executed in your ajax function. You might consider it as a way to go and seems a right approach to me.

Update: Based on the comment you(OP) made below, you can have a response created in following fashion

def bad_request(message):
    response = HttpResponse(json.dumps({'message': message}), 
        content_type='application/json')
    response.status_code = 400
    return response

When you want to return status 400, you simply do,

return bad_request(message='This is a bad request')

So following this, in your ajax error function, you can use following to get that message,

xhr.responseJSON.message
Comments