how to get access to error message from abort command when using custom error handler
Using a python flask server, I want to be able to throw an http error response with the abort command and use a custom response string and a custom message in the body
@app.errorhandler(400)
def custom400(error):
response = jsonify({'message': error.message})
response.status_code = 404
response.status = 'error.Bad Request'
return response
abort(400,'{"message":"custom error message to appear in body"}')
But the error.message variable comes up as an empty string. I can't seem to find documentation on how to get access to the second variable of the abort function with a custom error handler
Solution 1:
If you look at flask/__init__.py
you will see that abort
is actually imported from werkzeug.exceptions
. Looking at the Aborter
class, we can see that when called with a numeric code, the particular HTTPException
subclass is looked up and called with all of the arguments provided to the Aborter
instance. Looking at HTTPException
, paying particular attention to lines 85-89 we can see that the second argument passed to HTTPException.__init__
is stored in the description
property, as @dirn pointed out.
You can either access the message from the description
property:
@app.errorhandler(400)
def custom400(error):
response = jsonify({'message': error.description['message']})
# etc.
abort(400, {'message': 'custom error message to appear in body'})
or just pass the description in by itself:
@app.errorhandler(400)
def custom400(error):
response = jsonify({'message': error.description})
# etc.
abort(400, 'custom error message to appear in body')
Solution 2:
People rely on abort()
too much. The truth is that there are much better ways to handle errors.
For example, you can write this helper function:
def bad_request(message):
response = jsonify({'message': message})
response.status_code = 400
return response
Then from your view function you can return an error with:
@app.route('/')
def index():
if error_condition:
return bad_request('message that appears in body')
If the error occurs deeper in your call stack in a place where returning a response isn't possible then you can use a custom exception. For example:
class BadRequestError(ValueError):
pass
@app.errorhandler(BadRequestError)
def bad_request_handler(error):
return bad_request(str(error))
Then in the function that needs to issue the error you just raise the exception:
def some_function():
if error_condition:
raise BadRequestError('message that appears in the body')
I hope this helps.
Solution 3:
I simply do it like this:
abort(400, description="Required parameter is missing")
Solution 4:
flask.abort
also accepts flask.Response
abort(make_response(jsonify(message="Error message"), 400))