From 37c7a955d7b1e42a3db74c41b71a35b59f492d18 Mon Sep 17 00:00:00 2001 From: joeduffy Date: Fri, 20 Oct 2017 19:26:18 -0700 Subject: [PATCH] Optionally emit stack traces for errors If --logtostderr is passed, and an unhandled error occurs that was produced by the github.com/pkg/errors package, we will now emit the stack trace. Much easier for debugging purposes. --- pkg/util/cmdutil/exit.go | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/pkg/util/cmdutil/exit.go b/pkg/util/cmdutil/exit.go index ca611f3c9..9f3462acf 100644 --- a/pkg/util/cmdutil/exit.go +++ b/pkg/util/cmdutil/exit.go @@ -6,19 +6,36 @@ import ( "fmt" "os" + "github.com/golang/glog" + "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/pulumi/pulumi/pkg/diag" ) -// RunFunc wraps an error-returning run func with standard Lumi error handling. All Lumi commands should wrap +// RunFunc wraps an error-returning run func with standard Pulumi error handling. All Lumi commands should wrap // themselves in this to ensure consistent and appropriate error behavior. In particular, we want to avoid any calls to // os.Exit in the middle of a callstack which might prohibit reaping of child processes, resources, etc. And we wish to // avoid the default Cobra unhandled error behavior, because it is formatted incorrectly and needlessly prints usage. func RunFunc(run func(cmd *cobra.Command, args []string) error) func(*cobra.Command, []string) { return func(cmd *cobra.Command, args []string) { if err := run(cmd, args); err != nil { - ExitError(err.Error()) + msg := err.Error() + if stackerr, ok := err.(interface { + StackTrace() errors.StackTrace + }); ok { + // If there is a stack trace, and logging is enabled, append it. Otherwise, debug glog it. + stack := msg + "\n" + for _, f := range stackerr.StackTrace() { + stack += fmt.Sprintf("%+s\n", f) + } + if LogToStderr { + msg = stack + } else { + glog.V(3).Infof(stack) + } + } + ExitError(msg) } } }