Search code examples
pythonflaskflask-cache

How to invalidate or delete a redis cache object if an error in Flask view


I am facing an issue where I am using the Flask cache module and in the case I have a runtime error I don't want the view cached.

Can anyone advise how to do this?

Here is what I would like to achieve.

from flask import Flask    
from flask.ext.cache import Cache

app = Flask(__name__)
mycache = Cache()
mycache.init_app(app)

@mycache.cached()
@app.route('/myview')
def process_view():
    try:
        return get_something()
    except:
        return print_error_and_no_cache_this_view()

Any thoughts on how I stop this view being cached if I have an error?


Solution

  • You can call cache.delete_memoized in an after_this_request handler:

    # @cached needs to be invoked before @route
    # because @route registers the handler with Flask
    # and @cached returns a different function.
    # If you @route first and then @cache Flask will
    # always execute the *uncached* version.
    
    @app.route('/myview')
    @mycache.cached()
    def process_view():
        try:
            return get_something()
        except:
    
            @app.after_this_request
            def clear_cache(response):
                mycache.delete_memoized('process_view')
                return response
    
            return print_error_and_no_cache_this_view() 
    

    Alternately, looking at the code for Flask-Cache it appears it does not handle errors thrown by the view. So you could simply raise the error yourself and handle the exception with a separate handler:

    @app.route('/myview')
    @mycache.cached()
    def process_view():
        try:
            return get_something()
        except Exception as e:
            raise ProcessViewIssue(e)
    
    @app.errorhandler(ProcessViewIssue)
    def handle_process_view_error(e):
        return print_error()