'how to not have the flask server break when an error occurs? [closed]
I have made an API app using flask, that takes a number(decimal) as input and returns some string. This app breaks if I send a string and works fine after re-starting it. I don't want to restart every time some error happens during processing. How do i do this?
Here is my code:
from flask import Flask, request, jsonify
# initiating the app
flask_api_app = Flask(__name__)
# the app accepts requests via "GET" and "POST" methods
@flask_api_app.route("/", methods=["GET", "POST"])
def output_risk_and_report():
# getting json data from api call
json_data = request.get_json(force=True)
# now the processing part
if json_data['number'] < 2:
return jsonify(["the number is less than two"])
else:
return jsonify(["the number is not less than two"])
# main function, in which app will be run
if __name__ == "__main__":
# running the app on local host
flask_api_app.run(debug=True, host='127.0.0.1', port='8080')
example of call which doesn't break the app: {"number":4}
example of call which breaks the app: {"number":"adfa"}
What changes do I make in my code to accomplish this?
EDIT 1: i was naive to give that example in my question. in my original program, i may get an error when inserting data into database or may get an error with some arithmetic calculation or something. So, is there any way to tell flask to keep serving for new api requests and not break when an error occurs with only one api call.
Solution 1:[1]
You need to trigger a return with an error message, if whatever the user submits can't be expressed as an integer.
The following should work for submissions like 3 and '3'
# now the processing part
try:
number = int(json_data['number'])
except ValueError:
return jsonify(['Invalid submission'])
# Number is now type integer
if number < 2:
return jsonify(["the number is less than two"])
else:
return jsonify(["the number is not less than two"])
Solution 2:[2]
You can make a decorator that is a global exception handler:
import traceback
from flask import current_app
def set_global_exception_handler(app):
@app.errorhandler(Exception)
def unhandled_exception(e):
response = dict()
error_message = traceback.format_exc()
app.logger.error("Caught Exception: {}".format(error_message)) #or whatever logger you use
response["errorMessage"] = error_message
return response, 500
And wherever you create your app instance, you need to do this:
from xxx.xxx.decorators import set_global_exception_handler
app = Flask(__name__)
set_global_exception_handler(app)
This will handle all exceptions generated in your application along with whatever else you need to do to handle them. Hope this helps.
Solution 3:[3]
When looking into the documents we can find this behaviour:
handle_exception(e)
Handle an exception that did not have an error handler associated with it, or that was raised from an error handler. This always causes a 500 InternalServerError.
Always sends the got_request_exception signal.
If propagate_exceptions is True, such as in debug mode, the error will be re-raised so that the debugger can display it. Otherwise, the original exception is logged, and an InternalServerError is returned.
If an error handler is registered for InternalServerError or 500, it will be used. For consistency, the handler will always receive the InternalServerError. The original unhandled exception is available as e.original_exception.
A way to catch this errors and do something with it could be this:
@app.errorhandler(Exception)
def handle_exception(e):
# pass through HTTP errors
if isinstance(e, HTTPException):
return e
# now you're handling non-HTTP exceptions only
return render_template("500_generic.html", e=e), 500
Source and extra documentation if needed you can find here:
Solution 4:[4]
your problem is caused because your program runs in debug mode. for linux there is a tool called gunicorn. you should set up gunicorn and it will run again your flask app every time it crashes so you wont need to restart by yourself. i dont know if there is a tool for windows.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Gaurav Agarwal |
| Solution 3 | Wimanicesir |
| Solution 4 | Ibrahim Halici |
