I have a Flask application that works well and generates a random error that is visible when it works with debug=True :
if __name__ == '__main__': app.run(debug=True)
I get helpful error messages such as:
Traceback (most recent call last): File "./main.py", line 871, in index_route KeyError: 'stateIIIII'
I would like to receive error messages similar to those saved to a file when I launch the application during production (using Lighttpd + fastcgi).
Having studied various StackOverflow questions ( http://flask.pocoo.org/docs/errorhandling/ , http://docs.python.org/2/library/logging.html , etc.); Flask mailing list and a few blogs, there seems to be no easy way to send all the big error messages to a file - I need to use the Python protocol module to configure things. So I came up with the following code.
At the top of my application file, I have various imported products, followed by:
app = Flask(__name__) if app.debug is not True: import logging from logging.handlers import RotatingFileHandler file_handler = RotatingFileHandler('python.log', maxBytes=1024 * 1024 * 100, backupCount=20) file_handler.setLevel(logging.ERROR) app.logger.setLevel(logging.ERROR) app.logger.addHandler(file_handler)
Then I put the code for each route in a try / except statement and used traceback to find out which line the error came from and print a nice error message:
def some_route(): try: # code for route in here (including a return statement) except: exc_type, exc_value, exc_traceback = sys.exc_info() app.logger.error(traceback.print_exception(exc_type, exc_value, exc_traceback, limit=2)) return render_template('error.html')
And then right at the end of the file I delete debug=True . Although I do not think I need to do this, since the application is launched by the fastcgi server (?), When it starts in production. The last two lines of my application code are as follows:
if __name__ == '__main__': app.run()
I'm struggling to get this to work. I think that best of all I was able to get one error log message, which will be saved in a file using ( app.logger.error('test message') ), but it prints only one message. Attempting to register another error immediately after this is simply ignored.