Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Custom error message json object with flask-restful

It is easy to propagate error messages with flask-restful to the client with the abort() method, such as

abort(500, message="Fatal error: Pizza the Hutt was found dead earlier today
in the back seat of his stretched limo. Evidently, the notorious gangster
became locked in his car and ate himself to death.")

This will generate the following json output

{
  "message": "Fatal error: Pizza the Hutt was found dead earlier today
       in the back seat of his stretched limo. Evidently, the notorious gangster
       became locked in his car and ate himself to death.", 
  "status": 500
}

Is there a way to customise the json output with additional members? For example:

{
  "sub_code": 42,
  "action": "redirect:#/Outer/Space"
  "message": "You idiots! These are not them! You've captured their stunt doubles!", 
  "status": 500
}
like image 689
Derek Avatar asked Feb 07 '14 22:02

Derek


3 Answers

People tend to overuse abort(), while in fact it is very simple to generate your own errors. You can write a function that generates custom errors easily, here is one that matches your JSON:

def make_error(status_code, sub_code, message, action):     response = jsonify({         'status': status_code,         'sub_code': sub_code,         'message': message,         'action': action     })     response.status_code = status_code     return response 

Then instead of calling abort() do this:

@route('/') def my_view_function():     # ...     if need_to_return_error:         return make_error(500, 42, 'You idiots!...', 'redirect...')     # ... 
like image 156
Miguel Avatar answered Sep 20 '22 05:09

Miguel


I don't have 50 reputation to comment on @dappiu, so I just have to write a new answer, but it is really related to "Flask-RESTful managed to provide a cleaner way to handle errors" as very poorly documented here

It is such a bad document that took me a while to figure out how to use it. The key is your custom exception must inherit from flask_restful import HTTPException. Please note that you cannot use Python Exception.

from flask_restful import HTTPException

class UserAlreadyExistsError(HTTPException):
    pass

custom_errors = {
    'UserAlreadyExistsError': {
        'message': "A user with that username already exists.",
        'status': 409,
    }
}

api = Api(app, errors=custom_errors)

Flask-RESTful team has done a good job to make custom exception handling easy but documentation ruined the effort.

like image 40
Crespo Wang Avatar answered Sep 24 '22 05:09

Crespo Wang


As @Miguel explains, normally you shouldn't use exceptions, just return some error response. However, sometimes you really need an abort mechanism that raises an exception. This may be useful in filter methods, for example. Note that flask.abort accepts a Response object (check this gist):

from flask import abort, make_response, jsonify

json = jsonify(message="Message goes here")
response = make_response(json, 400)
abort(response)
like image 39
tokland Avatar answered Sep 20 '22 05:09

tokland