1

In a Python/Flask application, I have defined this endpoint that I expect to return 404 if a client tries to get an id that doesn't exist on my database.

For example:

@app.route('/plants/<int:plant_id>', methods=['GET'])
def get_plant(plant_id):
  try:
    plant = Plant.query.filter(Plant.id == plant_id).one_or_none()

    if plant is None:
      abort(404)

    return jsonify({
      'success': True,
      'plant': plant.format()
    })

  except:
    abort(422)

The problem is that when I try to execute it, it always seems to raise an exception and returns 422.

GET nonexistent plant on Postman returning 422

If I remove the try/except syntax, it works as expected and returns the 404. But I lose the capacity of handling exceptions... so it's not a solution for me.

Why am I doing wrong? How could I correctly trigger 404 without setting 404 as the except return?

Thanks!!

Анна
  • 1,248
  • 15
  • 26

1 Answers1

1

Ok, finally I was able to understand it and solve it. I post my findings here so maybe it could help someone in the future. :)

The answer is very basic, actually: every time I abort, I trigger an exception. So, when I aborted, no matter the status code I used, I fell into my except statement, which was returning 422 by default.

What I did to solve it was to implement a custom RequestError, and every time I have a controlled error, I trigger my custom error, which output I can control separately.

This is the implementation of my custom error:

class RequestError(Exception):
    def __init__(self, status):
        self.status = status
    def __str__(self):
        return repr(self.status)

And I've changed my route implementation for something like this: (note that I'm now handling first the custom error exception, and only then triggering a generic 422 error)

@app.route('/plants/<int:plant_id>', methods=['GET'])
def get_plant(plant_id):
  try:
    plant = Plant.query.filter(Plant.id == plant_id).one_or_none()

    if plant is None:
      raise RequestError(404)

    return jsonify({
      'success': True,
      'plant': plant.format()
    })

  except RequestError as error:
    abort(error.status)

  except:
    abort(422)

And that does it! \o/

Анна
  • 1,248
  • 15
  • 26