I am using Tornado (4.3) under Python (3.4) with Jinja2 (2.8) and things work well--except I am having trouble catching exceptions that Jinja2 raises while processing templates.
Since I am using @tornado.gen.coroutine and @run_on_executor decorators, I can't catch the exceptions with something like this:
try:
buf = template.render(data=this_data)
except Exception as e:
buf = '<html><body>Error rendering template.</body></html>'
When an exception is raised by Jinja2 while rendering, it is not caught by the except block. Instead, the exception bubbles up with a traceback like this:
Can't convert 'NoneType' object to str implicitly
['Traceback (most recent call last):\n', ' File "C:/Projects/OsPy/OsPy.py", line 1020, in background_process_post_authenticated\n buf = template.render(data=this_data)\n', ' File "C:\\Prog\\Python34\\lib\\site-packages\\jinja2\\environment.py", line 989, in render\n return self.environment.handle_exception(exc_info, True)\n', ' File "C:\\Prog\\Python34\\lib\\site-packages\\jinja2\\environment.py", line 754, in handle_exception\n reraise(exc_type, exc_value, tb)\n', ' File "C:\\Prog\\Python34\\lib\\site-packages\\jinja2\\_compat.py", line 37, in reraise\n raise value.with_traceback(tb)\n', ' File "
I do have a write_error method defined, so I can catch the exception that Tornado raises, but I don't have any visibility into detailed template errors encountered by Jinja2. This makes debugging difficult.
Can anyone share a pattern for handling detailed exceptions such as template errors thrown by Jinja2 when rendering from the template inside a @run_on_executor routine called from a @tornado.gen.coroutine method?