core: DynamicExpand can return diagnostics

We were previously _trying_ to handle diagnostics here but were not quite
doing it right because we were testing whether the resulting error was
nil rather than appending it to the diagnostics and then seeing if the
result has errors.

The difference here is important because it allows DynamicExpand to return
warnings without associated errors when needed. Previously the graph
walker would treat a warnings-only result as if it were an error.

Ideally we'd change DynamicExpand to return diagnostics directly, but we
previously decided against that because there were so many implementors
to update, and my intent for this change is to be surgical in the update
so we minimize risk of backporting the change into patch releases.
This commit is contained in:
Martin Atkins 2022-09-23 14:33:43 -07:00
parent dbaf6d63f3
commit a9bd4099d3
2 changed files with 11 additions and 2 deletions

View File

@ -82,8 +82,9 @@ func (g *Graph) walk(walker GraphWalker) tfdiags.Diagnostics {
log.Printf("[TRACE] vertex %q: expanding dynamic subgraph", dag.VertexName(v)) log.Printf("[TRACE] vertex %q: expanding dynamic subgraph", dag.VertexName(v))
g, err := ev.DynamicExpand(vertexCtx) g, err := ev.DynamicExpand(vertexCtx)
if err != nil { diags = diags.Append(err)
diags = diags.Append(err) if diags.HasErrors() {
log.Printf("[TRACE] vertex %q: failed expanding dynamic subgraph: %s", dag.VertexName(v), err)
return return
} }
if g != nil { if g != nil {

View File

@ -5,5 +5,13 @@ package terraform
// These nodes are given the eval context and are expected to return // These nodes are given the eval context and are expected to return
// a new subgraph. // a new subgraph.
type GraphNodeDynamicExpandable interface { type GraphNodeDynamicExpandable interface {
// DynamicExpand returns a new graph which will be treated as the dynamic
// subgraph of the receiving node.
//
// The second return value is of type error for historical reasons;
// it's valid (and most ideal) for DynamicExpand to return the result
// of calling ErrWithWarnings on a tfdiags.Diagnostics value instead,
// in which case the caller will unwrap it and gather the individual
// diagnostics.
DynamicExpand(EvalContext) (*Graph, error) DynamicExpand(EvalContext) (*Graph, error)
} }