A decorator that sets up an error context, captures errors, and tears down the context.

def pyquil_protect(func, log_filename="pyquil_error.log"):
    """
    A decorator that sets up an error context, captures errors, and tears down the context.
    """

    def pyquil_protect_wrapper(*args, **kwargs):
        global global_error_context

        old_error_context = global_error_context
        global_error_context = ErrorContext()
        global_error_context.filename = log_filename

        try:
            val = func(*args, **kwargs)
            global_error_context = old_error_context
            return val
        except Exception as e:
            global_error_context.dump_error(e, inspect.trace())
            global_error_context = old_error_context
            raise

    return pyquil_protect_wrapper