Catching a 500 server error in Flask

PythonFlask

Python Problem Overview


I love Flask's error catching. It's beautifully simple:

@app.errorhandler(404)
def pageNotFound(error):
	return "page not found"

works like charm. But it doesn't work for the 500 error code. I want to catch Python errors when something goes wrong an exception is raised in the code. Is that possible?

I should note that if I explicitly call return abort(500) in a view then the 500 errorhandler does work. So this is explicitly for when the Python code fails.

Is this possible?

Python Solutions


Solution 1 - Python

What you have described is, by default, how Flask works. My assumption is that you are running in debug mode, and therefore exceptions are being shown to you in the debug screen. Make sure debug mode is off, then try again. Here is a comment directly from the code itself:

> Default exception handling that kicks in when an exception occurs that > is not caught. In debug mode the exception will be re-raised > immediately, otherwise it is logged and the handler for a 500 internal > server error is used. If no such handler exists, a default 500 > internal server error message is displayed.

Solution 2 - Python

It works fine in my side:

from flask import Flask ,url_for,render_template,request,abort
from  werkzeug.debug import get_current_traceback
app = Flask(__name__)

@app.route('/')
def index():
    try:
        raise Exception("Can't connect to database")
    except Exception,e:
        track= get_current_traceback(skip=1, show_hidden_frames=True,
            ignore_system_exceptions=False)
        track.log()
        abort(500)
    return "index"

@app.errorhandler(500)
def internal_error(error):

    return "500 error"

@app.errorhandler(404)
def not_found(error):
    return "404 error",404

if __name__== "__main__":
    app.run(debug=True)

Flask will not set the error code for you, so make sure to also provide the HTTP status code when returning a response.

Solution 3 - Python

here is my code snippt

@app.route('/')
def index():
	raise Exception("Can't connect to database")


@app.errorhandler(Exception)
def exception_handler(error):
	return "!!!!"  + repr(error)

Solution 4 - Python

My solution to this was to turn on the propagation of exceptions, by modifying the config dictionary:

app = Flask(__name__)
...
app.config['PROPAGATE_EXCEPTIONS'] = True

Look at this other related question: https://stackoverflow.com/questions/18059937/flask-app-raises-a-500-error-with-no-exception

Solution 5 - Python

The issue is that within the code, not all Exceptions are HTTPException, but Flask catches these by default and returns a generic 500 error response (which may or may not include the original error message as described by @Mark Hildreth). Thus, using @app.errorhandler(500) will not catch those errors, since this happens before Flask returns the generic 500 error.

You would need to have a generic errorhandler(Exception) which works similar to except Exception: in python, which captures everything. A good solution is provided in Flask pallets projects:

from werkzeug.exceptions import HTTPException

@app.errorhandler(Exception)
def handle_exception(e):
    # pass through HTTP errors. You wouldn't want to handle these generically.
    if isinstance(e, HTTPException):
        return e

    # now you're handling non-HTTP exceptions only
    return render_template("500_generic.html", e=e), 500

You can also return JSON if you'd like and also include the original error message if you're in debug mode. E.g.

from flask import jsonify
from werkzeug.exceptions import HTTPException

debug = True  # global variable setting the debug config

@app.errorhandler(Exception)
def handle_exception(e):
    if isinstance(e, HTTPException):
        return e

    res = {'code': 500,
           'errorType': 'Internal Server Error',
           'errorMessage': "Something went really wrong!"}
    if debug:
        res['errorMessage'] = e.message if hasattr(e, 'message') else f'{e}'

    return jsonify(res), 500

Solution 6 - Python

this code catching 500 status code and get exception error

@app.errorhandler(Exception)
def all_exception_handler(e):
    error = str(traceback.format_exc())

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJ-bobView Question on Stackoverflow
Solution 1 - PythonMark HildrethView Answer on Stackoverflow
Solution 2 - PythonJoeView Answer on Stackoverflow
Solution 3 - PythonWebQubeView Answer on Stackoverflow
Solution 4 - PythonelachellView Answer on Stackoverflow
Solution 5 - PythonMakanView Answer on Stackoverflow
Solution 6 - PythonhmirView Answer on Stackoverflow