Re: [cherrypy-users] Jsonify error responses

1,099 views
Skip to first unread message

Sylvain Hellegouarch

unread,
Nov 6, 2012, 3:42:26 AM11/6/12
to cherryp...@googlegroups.com
Hi,

On Tue, Nov 6, 2012 at 3:03 AM, anh le <anh...@gmail.com> wrote:
Hello all,

I'm building a web service that clients expect json responses even in cases of error.

In Flask it looks like the following snippets:

I'm not familiar with CP and still struggle to learn to customize the tools/plugin. 
I try to implement in the following code but it doesn't seem work.
What is the right way to make a Json HTTPError in CP? 
------
import cherrypy
import json

def jsonify_error(*args, **kwargs):
response = cherrypy.response
response.headers['Content-Type'] = 'application/json'
response.body = json.dumps({'status': response.status, 'message': response.body})

cherrypy.tools.jsonify_error= cherrypy.Tool('after_error_response', jsonify_error, priority=20)

class Root(object):

def index(self):
return "Home page"
index.exposed = True

if __name__ == "__main__":
cp_config = { '/': {'tools.jsonify_error.on': True} }
 cherrypy.quickstart(Root(), '/', config=cp_config)

Hitting some url like http://localhost:8080/xyz still returns 404 html page.


You got the Tool design right, unfortunately, for some reason I cannot recall, specific CherryPy exceptions like HTTPRedirect and HTTPError (hence NotFound) are not propagated to the before_error_response and after_error_response hookpoints. They are not considered as errors but as exception-ish code path.

This is why your tool doesn't work here. Instead you want to use the custom error handling facility: http://docs.cherrypy.org/stable/refman/_cperror.html#unanticipated-errors

For instance with your code:

import cherrypy
import json

def jsonify_error(status, message, traceback, version):
    response = cherrypy.response
    response.headers['Content-Type'] = 'application/json'
    return json.dumps({'status': status, 'message': message})

class Root(object):
    def index(self):
        return "Home page"
    index.exposed = True

if __name__ == "__main__":
    cp_config = { '/': {'error_page.404': jsonify_error} }
    cherrypy.quickstart(Root(), '/', config=cp_config)


--
- Sylvain
http://www.defuze.org
http://twitter.com/lawouach

anh le

unread,
Nov 6, 2012, 10:08:07 PM11/6/12
to cherryp...@googlegroups.com

Thank you Sylvain, 

Your suggested solution is simple and just works.

With some small changes in the config, the api consumer is now happy with the error responses:

     cp_config = { '/api': {'error_page.default': jsonify_error} } 

Also your pointing to the custom error handling facility is helpful, don't know why I missed it. 

--
anh
Reply all
Reply to author
Forward
0 new messages