• Martin Atkins's avatar
    command: Early error message for missing cache entries of locked providers · d09510a8
    Martin Atkins authored
    In the original incarnation of Meta.providerFactories we were returning
    into a Meta.contextOpts whose signature didn't allow it to return an
    error directly, and so we had compromised by making the provider factory
    functions themselves return errors once called.
    
    Subsequent work made Meta.contextOpts need to return an error anyway, but
    at the time we neglected to update our handling of the providerFactories
    result, having it still defer the error handling until we finally
    instantiate a provider.
    
    Although that did ultimately get the expected result anyway, the error
    ended up being reported from deep in the guts of a Terraform Core graph
    walk, in whichever concurrently-visited graph node happened to try to
    instantiate the plugin first. This meant that the exact phrasing of the
    error message would vary between runs and the reporting codepath didn't
    have enough context to given an actionable suggestion on how to proceed.
    
    In this commit we make Meta.contextOpts pass through directly any error
    that Meta.providerFactories produces, and then make Meta.providerFactories
    produce a special error type so that Meta.Backend can ultimately return
    a user-friendly diagnostic message containing a specific suggestion to
    run "terraform init", along with a short explanation of what a provider
    plugin is.
    
    The reliance here on an implied contract between two functions that are
    not directly connected in the callstack is non-ideal, and so hopefully
    we'll revisit this further in future work on the overall architecture of
    the CLI layer. To try to make this robust in the meantime though, I wrote
    it to use the errors.As function to potentially unwrap a wrapped version
    of our special error type, in case one of the intervening layers is
    changed at some point to wrap the downstream error before returning it.
    d09510a8