4

I have a code like this

def find_user(user_id):
    if not users.lookup(user_id):
        return jsonify(success=False, reason="not found")
    else:
        return users.lookup(user_id)

@app.route(...)
def view1(...):
    user = find_user(...)
    if user:
       do_something
    return jsonify(success=True, ....)

The point is I have a helper function and if condition is met I want to return the response right away. In this case if user is not found, I want to return a request stating the request failed and give a reason.

The problem is because the function can also return some other values (say a user object) . I will not return from the request. Instead, because we got an assignment we will continue with the rest of the code path.

I probably can do a type check but that's ugly!

Ideally this is the longer code

def view(...)
    user = users.lookup(user_id)
    if not user:
       return jsonify(success=False....)
    # if user is true, do something else

The whole point of the helper function find_user is to extract out common code and then reuse in a few other similar apis.

Is there a way to return the response directly in my current code? It seems like this is a deadend... unless I change how the code is written (how values are returned...)

User007
  • 1,519
  • 6
  • 22
  • 35

2 Answers2

11

You should raise an exception in find_user, then add a handler that returns the proper response for that exception. An example from http://flask.pocoo.org/docs/patterns/apierrors/:

from flask import jsonify

class InvalidUsage(Exception):
    status_code = 400

    def __init__(self, message, status_code=None, payload=None):
        Exception.__init__(self)
        self.message = message
        if status_code is not None:
            self.status_code = status_code
        self.payload = payload

    def to_dict(self):
        rv = dict(self.payload or ())
        rv['message'] = self.message
        return rv

@app.errorhandler(InvalidAPIUsage)
def handle_invalid_usage(error):
    response = jsonify(error.to_dict())
    response.status_code = error.status_code
    return response

Using this example, in your find_user function, you could do:

raise InvalidUsage('User not found', status_code=404)
Russell Davis
  • 8,319
  • 4
  • 40
  • 41
3

As per this answer, you could also simply

return jsonify(success=False....), 400

to return a status code 400.

Community
  • 1
  • 1
Matthias
  • 3,160
  • 2
  • 24
  • 38