From a00c1a584f76a3b98b173559e056eb1f92a0023e Mon Sep 17 00:00:00 2001 From: Katy Moe Date: Tue, 14 Feb 2023 16:31:22 +0000 Subject: [PATCH] reinstate error wrapping for context errs --- tfexec/cmd_default.go | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/tfexec/cmd_default.go b/tfexec/cmd_default.go index fca9def9..b386c1cd 100644 --- a/tfexec/cmd_default.go +++ b/tfexec/cmd_default.go @@ -10,6 +10,24 @@ import ( "sync" ) +// cmdErr is a custom error type to be returned when a cmd exits with a context +// error such as context.Canceled or context.DeadlineExceeded. +// The type is specifically designed to respond true to errors.Is for these two +// errors. +// See https://github.com/golang/go/issues/21880 for why this is necessary. +type cmdErr struct { + err error + ctxErr error +} + +func (e *cmdErr) Is(target error) bool { + switch target { + case context.DeadlineExceeded, context.Canceled: + return e.ctxErr == context.DeadlineExceeded || e.ctxErr == context.Cancelled + } + return false +} + func (tf *Terraform) runTerraformCmd(ctx context.Context, cmd *exec.Cmd) error { var errBuf strings.Builder @@ -40,8 +58,11 @@ func (tf *Terraform) runTerraformCmd(ctx context.Context, cmd *exec.Cmd) error { } err = cmd.Start() - if err == nil && ctx.Err() != nil { - err = ctx.Err() + if ctx.Err() != nil { + return cmdErr{ + err: err, + ctxErr: ctx.Err(), + } } if err != nil { return err