terraform/internal/promising/errors.go
Martin Atkins 170cca1332 stacks+promising: Better error messages for promise resolution failure
We were previously just treating promising.ErrUnresolved as a singleton
that doesn't carry any context along with it. This particular error always
represents a bug in the stack runtime rather than a problem with the input,
because resolving all of the promises is a key part of the contract for
package promising, but it's still helpful to know a little more about what
exactly has failed when debugging it.

Therefore promising.ErrUnresolved is now a type rather than a value, and
its carries with it a set of promise ids that were left unresolved. The
stackeval package then recognizes this error type and uses its own records
of what each promise was supposed to produce to hopefully return a useful
error message that would narrow down what part of the system is buggy.

Since this message always reflects a bug in Terraform the error message
will probably just be copy-pasted into a bug report, and so this particular
diagnostic type (unlike the one we use for promise self-references) only
has one presentation form that we use regardless of how many promises
we have to return.
2024-07-23 08:32:25 -07:00

28 lines
992 B
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package promising
// ErrUnresolved is the error type returned by a promise getter or a main
// task execution if a task fails to resolve all of the promises it is
// responsible for before it returns.
type ErrUnresolved []PromiseID
func (err ErrUnresolved) Error() string {
return "promise unresolved"
}
// ErrSelfDependent is the error type returned by a promise getter if the
// requesting task is depending on itself for its own progress, by trying
// to read a promise that it is either directly or indirectly responsible
// for resolving.
//
// The built-in error message is generic but callers can type-assert to
// this type to obtain the chain of promises that lead from the task
// to itself, possibly via other tasks that are themselves awaiting the
// caller to resolve a different promise.
type ErrSelfDependent []PromiseID
func (err ErrSelfDependent) Error() string {
return "task is self-dependent"
}