2

I have one questions, which related to decorators. for example I wrote the next decorator, which handle the error, and then just output the error.

def handle_error(func):
    def wrapper(*args, **kwargs):
        try:
            return func(*args, **kwargs)
        except Exception as err:
            print(err)
    return wrapper


@handle_error
def raise_error():
    return 1 / 0

raise_error()

But, if I want to do the same with Flask it's doesn't work.

@app.route('/')
@handle_error
def index():
    return {'hello'}

if __name__ == '__main__':
    app.run()

So I'm guessing, the error raised in route decorator, am I right? if yes, I have question: Technically I can to write an decorator which will be handle all exceptions from route decorator?

  • Your `index()` view function is not raising any errors (returning a `set` is not an error) and us such your custom error handler is not raising any exceptions.What error did you expect to see? – Timusan Mar 03 '18 at 00:15
  • `index()` function, also will be called by `route` decorator, and in the this route we will get the error, and actually this, what I need. Control any flask errors via decorator. –  Mar 03 '18 at 09:51

3 Answers3

3

you can create an error handler something like this as I did in mine decorator

def error_handler() -> object:
    def wrapper(f):
        @wraps(f)
        def wrapped(*args, **kwargs):
            try:
                return f(*args, **kwargs)
            # handle different types of errors and return messages accordingly with status code
            except Exception as e:
                if isinstance(e, ValueError):
                    return jsonify({'message': e.args[0], 'type': 'ValueError'}), 400
                elif isinstance(e, AttributeError):
                    return jsonify({'message': e.args[0], 'type': 'AttributeError'}), 400
                elif isinstance(e, KeyError):
                    return jsonify({'message': e.args[0], 'type': 'KeyError'}), 400
                elif isinstance(e, TypeError):
                    return jsonify({'message': e.args[0], 'type': 'TypeError'}), 400
                else:
                    return jsonify({'message': str(e), 'type': 'InternalServerError'}), 500
        return wrapped
    return wrapper

if you want those errors to be logged in the file, you can import and set up logging where we initialize our flask application. log message, and error from except block.

Ankit Maurya
  • 111
  • 6
0

Flask already has the errorhandler() decorator, look here for a quick introduction.

You wouldn't use this for decorating your view functions, instead you use it to decorate your intended error handling functions.

Taking your example code, using this decorator could look something like this:

@app.route('/')
def index():
    return {'hello'}

@app.route('/dividebyzero')
def divbyzero():
    return 1 / 0

@app.errorhandler(404):
def handle_notfound(e):
    return 'we could not find the page'

@app.errorhandler(500):
def handle_intsrverr(e):
    return 'we stumbled upon some exception'

if __name__ == '__main__':
    app.run()
bgse
  • 8,237
  • 2
  • 37
  • 39
  • 1
    Thank you! I'm know about the `error_handler`, but I'm looking for a bit different, for example I need to write an `decorator`, which will handle error and write to log.files, or something this, So, I need to create own handler which will handle an errors, and will do own an flow and etc, and will not raises any HTTTP errors. –  Mar 03 '18 at 14:33
0

You can use errorhandler with logger.

logger = app.logger()

@app.errorhandler(500)
def somehandler(e):
    logger.critical(e.description) # this is level of logger

so when 500 error occurs, logger will work. also you can make your own error.

How can I implement a custom error handler for all HTTP errors in Flask?

KimJangHun
  • 43
  • 2
  • 8