Reputation: 739
from flask import Flask, abort, Response
from werkzeug.exceptions import HTTPException
app = Flask(__name__)
@app.errorhandler(HTTPException)
def http_exception_handler(e: HTTPException):
msg = 'http_exception_handler is called.'
print(msg)
return msg
@app.route('/')
def index():
try:
abort(Response('I am the response passed to abort.', 400))
except Exception as e:
print(f'Raised error is an instance of HTTPException: {isinstance(e, HTTPException)}')
raise e
return 'Index successfully produced a response.'
In the code above, why is the registered handler for HTTPException
not invoked when the abort
function is called with a Response
object? The execution of the code indicates the raised error by abort
is an instance of HTTPException
.
Upvotes: 2
Views: 1474
Reputation: 612
TL;DR: Don't pass a Response object. Use a HTTP code if you want to use the ErrorHandler.
So, it's more complicated as it looks like. You can dig into Werkzeug code and Flask to see what's going on. I'm not going to detail the steps.
So, the abort() is called on an Aborter class. That is going to create a HTTPException from the your Response object.
If you run the following command, you will have:
>>> print(HTTPException(response=Response("BODY",404)))
??? Unknown Error: None
This HTTPException has no code.
>>> print(HTTPException(response=Response("BODY", 404)).code)
None
This one is interpreted by the error handler.
def handle_http_exception(self, e):
if e.code is None:
return e # Here's your return
# This is never called.
handler = self._find_error_handler(e)
if handler is None:
return e
return handler(e)
Then your handler decorator will never be called.
So this a part of the detailed steps. But as Flask and Werkzeug are well coded. You can directly read here on the HTTPException class:
def get_response(self, environ=None):
"""Get a response object. If one was passed to the exception
it's returned directly.
It means what it means, it's returned directly. And that makes sens. Why would you go on a errorhandler if you have already managed the error.
If you want to go deeper in the code here some github links:
Werkzeug Exception Flask App class
Upvotes: 1