I am trying to catch an exception when using a Response object. My use case is that I want to stream data like described in the official documentation and that there is the possibility of an exception when I get the data that I want to stream:
# test.py
from flask import Flask, Response, jsonify
import werkzeug
app = Flask(__name__)
@app.route("/")
def hello():
def generate():
raise Exception
for i in range(0,10):
yield '1'
try:
return Response(generate())
except Exception:
return jsonify("error") # expected this but instead 500 server error is returned
if __name__ == '__main__':
app.run()
When I then run the server and request the data, I would expect to see "error" but instead an Internal Server Error message from Flask is shown.
FLASK_APP=test.py flask run
curl http://localhost:5000/
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>500 Internal Server Error</title>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error and was unable to
complete your request. Either the server is overloaded or there is
an error in the application.</p>
In some way the exception gets raised, as we can see it in stdout but does not get catched by Flask. I also tried to make sure that the exception does not get catched by setting passthrough_errors option of the werkzeug server. Then the exception does not get catched in Werkzeug e.g. here or here. Unfortunately this did not helped for catching it in the Flask application above:
app.run(passthrough_errors=True)
Output of flask --version:
Flask 1.0.2
Python 3.7.0 (default, Aug 22 2018, 15:22:33)
[Clang 9.1.0 (clang-902.0.39.2)]
UPDATE: This problem also occurs when I am not using the streaming:
from flask import Flask, Response, jsonify
app = Flask(__name__)
@app.route("/")
def hello():
try:
return Response(2)
except Exception as error:
return jsonify({'error': error})
if __name__ == '__main__':
app.run(passthrough_errors=False)
A TypeError gets raised on Flask side, because the Integer is not iterable but the exception does not get catched.
FLASK_APP=test.py flask run
curl http://localhost:5000/
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>500 Internal Server Error</title>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error and was unable to
complete your request. Either the server is overloaded or there is
an error in the application.</p>