Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In pyramid how to return 400 response with json data?

I have the following jquery code:

$.ajax({
    type: 'POST',
    url: url,
    data: data,
    dataType: 'json',
    statusCode: {
        200: function (data, textStatus, jqXHR) {
                console.log(data);
            },
        201: function (data, textStatus, jqXHR) {
                 log(data);
            },
        400: function(data, textStatus, jqXHR) {
                log(data);
            },
    },
});

the 400 is used when the validation in backend (Pyramid) fails. Now from Pyramid how do I return HTTPBadRequest() response together with a json data that contains the errors of validation? I tried something like:

response = HTTPBadRequest(body=str(error_dict)))
response.content_type = 'application/json'
return response

But when I inspect in firebug it returns 400 (Bad Request) which is good but it never parses the json response from data.responseText above.

like image 421
Marconi Avatar asked Jul 20 '11 05:07

Marconi


2 Answers

Well you should probably start off by serializing the error_dict using a json library.

import json
out = json.dumps(error_dict)

Given that you don't give any context on how your view is setup, I can only show you how I would do it:

@view_config(route_name='some_route', renderer='json')
def myview(request):
    if #stuff fails to validate:
        error_dict = # the dict
        request.response.status = 400
        return {'errors': error_dict}

    return {
        # valid data
    }

If you want to create the response yourself, then:

response = HTTPBadRequest()
response.body = json.dumps(error_dict)
response.content_type = 'application/json'
return response

To debug the issue, stop going based off of whether jQuery works and look at the requests yourself to determine if Pyramid is operating correctly, or if it is something else that's going on.

curl -i <url>

Or even just open up the debugger in the browser to look at what is being returned in the response.

like image 100
Michael Merickel Avatar answered Oct 15 '22 03:10

Michael Merickel


I found a simple way to do it more generic then the accepted answer, I got it with this code

I include exception_response in my view

from pyramid.httpexceptions import exception_response

I raise the 400 exception where I need to

 raise exception_response(400)

In my exceptions script, I trap all exceptions to return generic json and I trap 400 to return a specific json

from pyramid.view import exception_view_config

from pyramid.httpexceptions import (
    HTTPException,
    HTTPBadRequest
)


@exception_view_config(HTTPException, renderer='json')
def exc_view_exception(message, request):
    return {'error': str(message)}


@exception_view_config(HTTPBadRequest, renderer='json')
# Exception 400 bad request
def exc_view_bad_request(message, request):
    body = {
        "message": str(message),
        "status": 400
    }
    request.response.status = 400
    return body
like image 31
Michael Avatar answered Oct 15 '22 02:10

Michael