plugin/convert: Show approximate location context for all provider errors
Even if a provider doesn't indicate a specific attribute as the cause of a resource operation error, we know the error relates to some aspect of the resource, so we'll include that approximate information in the result so that we don't produce user-hostile error messages with no context whatsoever. Later we can hopefully refine this to place the source range on the header of the configuration block rather than on an empty part of the body, but that'll require some more complex rework here and so for now we'll just accept this as an interim state so that the user can at least figure out which resource block the error is coming from.
This commit is contained in:
parent
fd77e56fd6
commit
e25f79ed28
|
@ -69,7 +69,7 @@ func ProtoToDiagnostics(ds []*proto.Diagnostic) tfdiags.Diagnostics {
|
|||
path := AttributePathToPath(d.Attribute)
|
||||
newDiag = tfdiags.AttributeValue(severity, d.Summary, d.Detail, path)
|
||||
} else {
|
||||
newDiag = tfdiags.Sourceless(severity, d.Summary, d.Detail)
|
||||
newDiag = tfdiags.WholeContainingBody(severity, d.Summary, d.Detail)
|
||||
}
|
||||
|
||||
diags = diags.Append(newDiag)
|
||||
|
|
|
@ -274,3 +274,46 @@ func (d *attributeDiagnostic) Source() Source {
|
|||
Subject: d.subject,
|
||||
}
|
||||
}
|
||||
|
||||
// WholeContainingBody returns a diagnostic about the body that is an implied
|
||||
// current configuration context. This should be returned only from
|
||||
// functions whose interface specifies a clear configuration context that this
|
||||
// will be resolved in.
|
||||
//
|
||||
// The returned attribute will not have source location information until
|
||||
// context is applied to the containing diagnostics using diags.InConfigBody.
|
||||
// After context is applied, the source location is currently the missing item
|
||||
// range of the body. In future, this may change to some other suitable
|
||||
// part of the containing body.
|
||||
func WholeContainingBody(severity Severity, summary, detail string) Diagnostic {
|
||||
return &wholeBodyDiagnostic{
|
||||
diagnosticBase: diagnosticBase{
|
||||
severity: severity,
|
||||
summary: summary,
|
||||
detail: detail,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type wholeBodyDiagnostic struct {
|
||||
diagnosticBase
|
||||
subject *SourceRange // populated only after ElaborateFromConfigBody
|
||||
}
|
||||
|
||||
func (d *wholeBodyDiagnostic) ElaborateFromConfigBody(body hcl.Body) Diagnostic {
|
||||
if d.subject != nil {
|
||||
// Don't modify an already-elaborated diagnostic.
|
||||
return d
|
||||
}
|
||||
|
||||
ret := *d
|
||||
rng := SourceRangeFromHCL(body.MissingItemRange())
|
||||
ret.subject = &rng
|
||||
return &ret
|
||||
}
|
||||
|
||||
func (d *wholeBodyDiagnostic) Source() Source {
|
||||
return Source{
|
||||
Subject: d.subject,
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue