Handle errors in a tornado application, the right way
Exceptions... allow error handling to be organized cleanly in a central or high-level place within the program structure.
Doug Hellmann, Python Exception Handling Techniques
After a few false steps, seems like, I found the right way to handle errors in a tornado application.
Main points:
- use ApplicationException(inherited from tornado.web.HTTPError) exception to return the application custom errors (like "user was not found" or "specified age is invalid")
- override tornado.web.RequestHandler.write_error, make it return errors in json format
See my question on stackoverflow.
import json import traceback from tornado import web, options, ioloop class MyAppException(web.HTTPError): pass class MyAppBaseHandler(web.RequestHandler): def write_error(self, status_code, **kwargs): self.set_header('Content-Type', 'application/json') if self.settings.get("serve_traceback") and "exc_info" in kwargs: # in debug mode, try to send a traceback lines = [] for line in traceback.format_exception(*kwargs["exc_info"]): lines.append(line) self.finish(json.dumps({ 'error': { 'code': status_code, 'message': self._reason, 'traceback': lines, } })) else: self.finish(json.dumps({ 'error': { 'code': status_code, 'message': self._reason, } })) class AgeHandler(MyAppBaseHandler): def get(self): age = self.get_argument('age') age = int(age) if age < 1 or age > 200: raise MyAppException(reason='Wrong age value.', status_code=400) self.write('Your age is {age}'.format(age=age)) class MyApplication(web.Application): def __init__(self, **kwargs): kwargs['handlers'] = [ web.url(r'/', AgeHandler, name='age'), ] kwargs['debug'] = True super(MyApplication, self).__init__(**kwargs) if __name__ == '__main__': options.parse_command_line() application = MyApplication() application.listen(5000) ioloop.IOLoop.instance().start()
debug == False:
{ "error":{ "code":400, "message":"Wrong age value." } }
debug == True:
{ "error":{ "traceback":[ "Traceback (most recent call last):\n", " File \".env/lib/python3.3/site-packages/tornado/web.py\", line 1332, in _execute\n result = method(*self.path_args, **self.path_kwargs)\n", " File \"app.py\", line 46, in get\n raise MyAppException(reason='Wrong age value.', status_code=400)\n", "MyAppException: HTTP 400: Wrong age value.\n" ], "message":"Wrong age value.", "code":400 } }
Licensed under CC BY-SA 3.0