Reputation: 7038
Python 3 introduced exception chaining, so this:
import logging
logger = logging.getLogger(__name__)
class MyException(Exception):
pass
def blow_up():
try:
impossible = 42 / 0
except ZeroDivisionError as zde:
raise MyException('Uh oh!') from zde
try:
blow_up()
except:
logger.exception('It blew up!')
Produces this:
It blew up!
Traceback (most recent call last):
File "ka-boom.py", line 10, in blow_up
impossible = 42 / 0
ZeroDivisionError: division by zero
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "ka-boom.py", line 15, in <module>
blow_up()
File "ka-boom.py", line 12, in blow_up
raise MyException('Uh oh!') from zde
MyException: Uh oh!
But when an unhandled exception gets thrown in a Flask view method, the __cause__
doesn't get logged, which makes debugging hard.
I can do this:
@app.errorhandler(Exception)
def better_exception_handler(error):
current_app.logger.exception('Whoopsie!')
return 'Internal server error', 500
but I feel uncomfortable capturing all exceptions like this, and it doesn't feel very elegant. Is there a way to get Flask's built-in exception handler to log the chained exception?
Upvotes: 5
Views: 2800
Reputation: 303
Can you supply the version of Python and Flask that you're using? With Python 3.5.2 and Flask 0.12.1 I'm seeing what you're saying should happen.
from flask import Flask
app = Flask(__name__)
@app.route('/error')
def error_out():
try:
blow_up()
except:
app.logger.exception('it blew up!')
return 'something went wrong'
return 'everything is a-ok!'
def blow_up():
try:
impossible = 42 / 0
except ZeroDivisionError as zde:
raise MyExc('Uh oh!') from zde
class MyExc(Exception):
pass
if __name__ == "__main__":
app.run()
Hitting localhost:5000/error
for me will then log the following in the console:
Seaking:flask-err rdbaker $ ~/.pyenv/versions/3.5.2/bin/python app.py
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
[2017-05-15 12:19:52,229] ERROR in app: it blew up!
Traceback (most recent call last):
File "app.py", line 21, in blow_up
impossible = 42 / 0
ZeroDivisionError: division by zero
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "app.py", line 12, in error_out
blow_up()
File "app.py", line 23, in blow_up
raise MyExc('Uh oh!') from zde
MyExc: Uh oh!
127.0.0.1 - - [15/May/2017 12:19:52] "GET /error HTTP/1.1" 200 -
and I see the text something went wrong
in my browser.
Upvotes: 2