what is error handling best practice in Flask restAPI

0

Issue

Flask==1.1.2
Python==3.8

I am building a restAPI that is serving machine learning model. My co-worker who will be sending request to my restAPI and use the outcome to send it to users wants me to send him appropriate error message as well with status_code.

I’ve did a lot of searching on how to properly handle errors in Python Flask however I am still stuck on what would be a best practice for scalable and maintainable restAPI.

Currently whenever some error occurs I simply return dictionary with message and status code. There are some problems with this method that I want to mitigate:

  1. If error occurs inside a function it has to return dictionary containing error messages to where the function was called and at need to check if it was actually an error, if yes then return error message

    Example:

     def add_data(x,y):
         """return addition of x,y. They both need to be integers"""
         if type(x) != int:
             return "x has wrong datatype"
         if type(y) != int:
             return "y has wrong datatype"
         return x+y
    
     @app.route("/predict", methods=["POST"])
     def predict():
         data = request.get_json()
         result = add_data(data["x"], data["y"])
         if type(result) == str:
             return {"message":"input error", "status":222}
    
  2. Cannot break code inside a function.

    following some references

    I’ve changed my code to following:

     class InputError(Exception):
         status_code = 400
         def __init__(self, message, status_code=None):
             Exception.__init__(self)
             self.message = message
             if status_code is not None:
                 self.status_code = status_code
    
         def __str__(self):
             return repr(self.status_code)
    
    
     def add_data(x,y):
         if type(x) != int:
             raise InputError("x has wrong datatype", status_code=222)
         if type(y) != int:
             raise InputError("y has wrong datatype", status_code=222)
         return x+y
    

    This does break the code where error is found however I cannot find out how to return dictionary just like before.

How can I do this and which practice is considered a best practice?

Solution

The solution is to use error handlers
https://flask.palletsprojects.com/en/1.1.x/errorhandling/

In your case:

@app.errorhandler(InputError)
def handle_input_error(e):
    return {"message": e["message"], "status": e["status"]}

Now whenever you raise InputError somewhere in the code, flask will know to call this method and return this response

If you have more types of errors I would switch to something more general

class MyErrors(Exception):
    status_code: int
    
    def __init__(self, message):
        super(MyErrors, self).__init__(message)
        self.message = message
        
    def response(self):
        return {"message": self.message, "status": self.status_code}
    
class InputError(MyErrors):
    status_code = 222
    
class SomeOtherError(MyErrors):
    status_code = 123

@app.errorhandler(MyErrors)
def handle_errors(e):
    return e.response()

Answered By – Ron Serruya

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave A Reply

Your email address will not be published.

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More