1

I am using Flask-RESTful abort() method when constructing an error response in REST. The example given has a named argument message

def abort_if_todo_doesnt_exist(todo_id):
    if todo_id not in TODOS:
        abort(404, message="Todo {} doesn't exist".format(todo_id))

The output is

{
    "message": "Todo asd doesn't exist. You have requested this URI [/todos/asd] but did you mean /todos/<todo_id> or /todos ?"
}

In my scenario, I already have a custom exception type

class InvalidParameter(Exception):
    status_code = 400

    def __init__(self, message, status_code=None, resource=None,
                field=None, code=None, stack_trace=None):
        Exception.__init__(self)
        self.message = message
        if status_code is not None:
            self.status_code = status_code
        self.resource = resource
        self.field = field
        self.code = code
        self.stack_trace = stack_trace

    def to_dict(self):
        rv = {}
        error = {}
        rv['message'] = self.message
        error['resource'] = self.resource
        error['field'] = self.field
        error['code'] = self.code
        error['stack_trace'] = self.stack_trace
        rv['error'] = error
        return rv

and a specific structure of JSON response for errors:

{
    "message": "Project name 'GGO' already exist.",
    "error": {
        "resource": "Project",
        "field": "project_name",
        "code": "already_exists",
        "stack_trace": "(psycopg2.IntegrityError) duplicate key value violates unique ..."
    }
}

Problem Code

I have to use two named arguments

except InvalidParameter as err:
    abort(err.status_code, 
                message=err.to_dict()['message'], 
                error=err.to_dict()['error'])

When I use this except InvalidParameter as err: abort(err.status_code, err.to_dict())

I get the error

TypeError: abort() takes 1 positional argument but 2 were given // Werkzeug Debugger

How can I pass the entire err dict as a parameter?

Hanxue
  • 12,243
  • 18
  • 88
  • 130
  • 1
    According to the [source code](https://github.com/flask-restful/flask-restful/blob/master/flask_restful/__init__.py), `abort` takes only 1 positional argument (`http_status_code`) along with any number of `kwargs`. This is why it errs with the `TypeError` when you pass 2 positional arguments. You can use dict unpacking `**dict`, to pass along all the key arguments from your `err` variable - `abort(err.status_code, **err)` – shad0w_wa1k3r Aug 22 '17 at 07:28
  • Thank you @AshishNitinPatil, that is the solution. Would you want to officially answer before I link this question as a duplicate? – Hanxue Aug 22 '17 at 13:29
  • I have already answered it, but answering a dupe is not encouraged, so have deleted my answer. You should close this off as a dupe. – shad0w_wa1k3r Aug 22 '17 at 13:30

0 Answers0