How Can I Implement A Custom Error Handler For All HTTP Errors In Flask?
Solution 1:
You can use the errorhandler
decorator with an exception class rather than an error code as an argument, as is described here. Thus you could try for instance
@application.errorhandler(HTTPException)
def http_error_handler(error):
to handle all HTTP errors (which presumably means all HTTP error codes), or even
@application.errorhandler(Exception)
def http_error_handler(error):
to handle all uncaught exceptions
Edit: Having looked at the flask source code, there is a 'TRAP_HTTP_EXCEPTIONS' flag in the app config, which you can change (by doing for instance app.config['TRAP_HTTP_EXCEPTIONS']=True
).
(Roughly) When this flag is false, exceptions which are instances of HTTPException are handled by the functions you've decorated with errorhandler(n)
where n
is an HTTP error code; and when this flag is true, all instances of HTTPException are instead handled by the functions you've decorated with errorhandler(c)
, where c is an exception class.
Thus doing
app.config['TRAP_HTTP_EXCEPTIONS']=True
@application.errorhandler(Exception)
def http_error_handler(error):
should achieve what you want.
Since it looks like HTTPException has subclasses for each HTTP error code (see here), setting 'TRAP_HTTP_EXCEPTIONS' and decorating your error handlers with exception classes not error codes looks like a strictly more flexible way of doing things.
For reference, my flask error handling now looks like:
app.config['TRAP_HTTP_EXCEPTIONS']=True
@app.errorhandler(Exception)
def handle_error(e):
try:
if e.code < 400:
return flask.Response.force_type(e, flask.request.environ)
elif e.code == 404:
return make_error_page("Page Not Found", "The page you're looking for was not found"), 404
raise e
except:
return make_error_page("Error", "Something went wrong"), 500
This does everything I want, and seems to handle all errors, both HTTP and internal. The if e.code < 400
bit is there to use flask's default behaviour for redirects and the like (otherwise those end up as error 500s, which isn't what you want)
Solution 2:
You're not the only one, one workaround will be specifying the list of the http error code you're catching and bound to application.error_handler_spec, and drop the decorators, like this:
def http_error_handler(error):
return flask.render_template('error.html', error=error), error.code
for error in (401, 404, 500): # or with other http code you consider as error
application.error_handler_spec[None][error] = http_error_handler
Not ideal and ugly I know, but it will work and I do hope someone else can come with a better solution. Hope this helps.
Solution 3:
For me, the following snippets was not working :
@app.errorhandler(HTTPException)
def _handle_http_exception(e):
return make_response(render_template("errors/http_exception.html", code=e.code, description=e.description), e.code)
But changing HTTPException
to the real one, like NotFound
, was working. Don't ask me why, I didn't find the answer.
So I've found an alternative solution which works pretty well:
from werkzeug.exceptions import default_exceptions
def _handle_http_exception(e):
return make_response(render_template("errors/http_exception.html", code=e.code, description=e.description), e.code)
for code in default_exceptions:
app.errorhandler(code)(_handle_http_exception)
(Found at Github)
Post a Comment for "How Can I Implement A Custom Error Handler For All HTTP Errors In Flask?"