10

I'm currently writing a REST API for an app I'm working on. The app is written in python using flask. I have the following:

try:
    _profile = profile(
        name=request.json['name'],
        password=profile.get_salted_password('blablabla'),
        email=request.json['email'],
        created_by=1,
        last_updated_by=1
    )
except AssertionError:
    abort(400)

session = DatabaseEngine.getSession()
session.add(_profile)
try:
    session.commit()
except IntegrityError:
    abort(400)

The error handler looks like this:

@app.errorhandler(400)
def not_found(error):
    return make_response(standard_response(None, 400, 'Bad request'), 400)

I'm using the error 400 to denote both a problem with a sqlalchemy model validator and a unique constraint when writing to the database and in both cases the following error is sent to the client:

{
  "data": null,
  "error": {
    "msg": "Bad request",
    "no": 400
  },
  "success": false
}

Is there a way to still use abort(400) but also set the error somehow so that the error handler can take care of adding additional information for the error object in the result?

I would like it to be more in line with:

{
  "data": null,
  "error": {
    "msg": "(IntegrityError) duplicate key value violates unique constraint profile_email_key",
    "no": 400
  },
  "success": false
}

3 Answers 3

9

you can directly put a custom response in abort() function:

abort(make_response("Integrity Error", 400))

Alternatively, you can put it in the error handler function

@app.errorhandler(400)
def not_found(error):
resp = make_response("Integrity Error", 400)
return resp
Sign up to request clarification or add additional context in comments.

3 Comments

It works to produce the output but it seems like the error 400 handler is not being called if I do this. Is there a way to still end up there since I was planning on doing some logging in the error handlers?
Yeah, that won't work since then I'm back where I started where all 400 will be Integrity Error instead of Bad Request. I need to make both custom error text and end up in the error handler. :)
abort does not take a response in the current api. flask.pocoo.org/docs/api
8

errorhandler can take an exception type as well:

@app.errorhandler(AssertionError)
def handle_sqlalchemy_assertion_error(err):
    return make_response(standard_response(None, 400, err.message), 400)

2 Comments

Yup, this was the one I was looking for. Is there a way to catch errors not bound to a handler like a "catch-all" so I can format and handle that to the client too?
That make_response and standard_response doesn't work for me. But this does: "def handle_sqlalchemy_error(err): return err.message, 400"
0

i know am late to the game, but for anyone who wants another solution, mine is based on the answer by @codegeek.

i was able to accomplish something similar with the following in my ServerResponse.py module:

def duplicate(message=""):
    response = make_response()
    response.status_code = 409
    response.headers = {
        "X-Status-Reason" : message or "Duplicate entry"
    }
    abort(response)

then i can call

ServerResponse.duplicate('Duplicate submission. An article with a similar title already exists.')

this makes it easy in my AngularJS app to check for a response status and display the X-Status-Reason default or customized message

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.