From 2bbc3d50d778f3dc47b77dab06b9613337506614 Mon Sep 17 00:00:00 2001 From: Megan Marsh Date: Mon, 8 Jul 2019 13:49:14 -0700 Subject: [PATCH] better error handling when using interpolate funcs; don't swallow func errors --- packer/core.go | 12 +++++++++--- template/interpolate/funcs.go | 10 +++++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/packer/core.go b/packer/core.go index 507c79b81..2a6210356 100644 --- a/packer/core.go +++ b/packer/core.go @@ -366,9 +366,15 @@ func (c *Core) init() error { c.variables[k] = renderedV ctx.UserVariables = c.variables case ttmp.ExecError: - shouldRetry = true - failedInterpolation = fmt.Sprintf(`"%s": "%s"`, k, v) - continue + castError := err.(ttmp.ExecError) + switch castError.Err.(type) { + case interpolate.ErrVariableNotSet: + shouldRetry = true + failedInterpolation = fmt.Sprintf(`"%s": "%s"; error: %s`, k, v, err) + continue + default: + return err + } default: return fmt.Errorf( // unexpected interpolation error: abort the run diff --git a/template/interpolate/funcs.go b/template/interpolate/funcs.go index 57495052a..f2842bc16 100644 --- a/template/interpolate/funcs.go +++ b/template/interpolate/funcs.go @@ -47,6 +47,14 @@ var FuncGens = map[string]FuncGenerator{ "lower": funcGenPrimitive(strings.ToLower), } +type ErrVariableNotSet struct { + Var string // Name of template. +} + +func (e ErrVariableNotSet) Error() string { + return fmt.Sprintf("variable %s not set", e.Var) +} + // FuncGenerator is a function that given a context generates a template // function for the template. type FuncGenerator func(*Context) interface{} @@ -168,7 +176,7 @@ func funcGenUser(ctx *Context) interface{} { // error and retry if we're interpolating UserVariables. But if // we're elsewhere in the template, just return the empty string. if !ok { - return "", errors.New(fmt.Sprintf("variable %s not set", k)) + return "", ErrVariableNotSet{k} } } return val, nil