There are two similar handlers: AgeHandler1 and AgeHandler2. In the first one we simply raise a specific exception to return an error message, in the second - we manually return
Overwriting write_error works very well. What I do in my projects is I try to catch any 500
status codes. I then send them to myself over slack (my traffic is low enough that the frequency is very low).
Here's the code to extract a clean stack trace from write_error
. Note in this example I also yank out any references to 'gen.py', 'concurrent.py' or 'web.py', which makes for much cleaner stack traces.
import tornado.web, traceback, logging
class MyRequestHandler(tornado.web.RequestHandler):
def write_error(self,status_code,**kwargs):
if status_code == 500:
excp = kwargs['exc_info'][1]
tb = kwargs['exc_info'][2]
stack = traceback.extract_tb(tb)
clean_stack = [i for i in stack if i[0][-6:] != 'gen.py' and i[0][-13:] != 'concurrent.py']
error_msg = '{}\n Exception: {}'.format(''.join(traceback.format_list(clean_stack)),excp)
# do something with this error now... e.g., send it to yourself
# on slack, or log it.
logging.error(error_msg) # do something with your error...
# don't forget to show a user friendly error page!
self.render("oops.html")
The output looks like this:
File "app.py", line 55, in get
assert 1==2,"A fake error to trigger a critical alert."
Exception: A fake error to trigger a critical alert.