1

i am currently working on my api and wanted to implement a mechanism that i can raise a custom exception at any point and return a json response:

class InvalidUsage(Exception):
    def __init__(self, message):
        Exception.__init__(self)
        self.message = message

    def to_json(self):
        return JsonResponse(False, self.message)()

class JsonResponse(object):
    def __init__(self, success, data):
        self.success = success
        self.data = data

        if not success:
            self.result = {
                'success': self.success,
                'error': self.data
            }
        else:
            self.result = {
                'success': self.success,
                'data': self.data
            }

    def __call__(self):
        return jsonify({'result': self.result})

When i try to use it in any controller:

raise InvalidUsage('Some error ocurred').to_json()

it just prints a Traceback back to:

raise InvalidUsage('Some error ocurred').to_json()

But JsonResponse works perfectly fine. When i run:

return JsonResponse(False, 'Some error ocurred')()

it returns correct json to my browser.

But i need to get my exception raise somehow working.. so i can raise api exceptions at any point in my python-webapp(controller, service, validator, etc..)

Anybody could help me to figure out how to do this?

Thanks and Greetings!

4
  • 1
    Flask specifically states that a custom error without an exception handler would cause a 500 server error: flask.pocoo.org/docs/0.12/patterns/apierrors Have you tried implementing the handler and raising just the error, without calling .to_json() on it? I'm also not sure I understand why you would call .to_json() when raising the exception. Commented Jul 1, 2017 at 13:48
  • i implemented the exact same like in the documentation, but with same result Commented Jul 1, 2017 at 13:51
  • Why do you call .to_json() then? I mean probably what you should do is call to_json from the error handler, not from the raise instruction Commented Jul 1, 2017 at 13:53
  • 1
    I don't see how your raise instruction could possibly work since raise accepts an object inheriting from BaseException and your are giving it a flask Response via jsonify Commented Jul 1, 2017 at 14:04

1 Answer 1

1

Firstly, if you want to call the constructor of a parent class, you should call super

class InvalidUsage(Exception):
    def __init__(self, message):
        super(InvalidUsage, self).__init__()
        self.message = message

Second, overriding __call__ is just ugly and a bad idea. You should either implement an explicit method, or define a custom __repr__ since JSON is just a string.

Third,

self.result = {
    'success': self.success,
    'data': self.data
}

is executed on both if and else. Why do you even have an if? Why not:

class JsonResponse(object):
    def __init__(self, success, data):
        self.success = success
        self.data = data

    def __repr__(self):
        return json.dumps({'success': self.success, 'data': self.data})

which makes this class more pointless than ever if it isn't used anywhere else in the code.

Fourth, when you want to raise a custom exception, you should raise the class InvalidUsage not a particular method in it.

raise InvalidUsage("terrible usage")

You should really think clearly about what you're doing here. You're throwing Exceptions. You can't throw an instance of a Flask.Response() object as an exception. What you can do is throw your custom InvalidUsage exception, catch it, and then return your json response:

class InvalidUsage(Exception)
    pass


def horrible_code():
    raise InvalidUsage("something went wrong.")


try:
    horrible_code()

except InvalidUsage as error:
    return jsonify({"success": "nope", "error_message": str(error)})
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.