From 440f54d08cb18f820941e599b8c8d6598b45833a Mon Sep 17 00:00:00 2001 From: Mike Solomon Date: Sat, 5 Jan 2013 16:31:35 -0800 Subject: [PATCH] prep new error handling --- go/cmd/vtctl/vtctl.go | 2 +- go/relog/panic.go | 33 ++++++++++++++++++++++++++------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/go/cmd/vtctl/vtctl.go b/go/cmd/vtctl/vtctl.go index 95ef85e5be..5baf462067 100644 --- a/go/cmd/vtctl/vtctl.go +++ b/go/cmd/vtctl/vtctl.go @@ -1264,7 +1264,7 @@ func commandApplySchemaKeyspace(wrangler *wr.Wrangler, subFlags *flag.FlagSet, a func main() { defer func() { if panicErr := recover(); panicErr != nil { - relog.Fatal("%v", relog.NewPanicError(panicErr.(error)).String()) + relog.Fatal("panic: %v", relog.Errorf("%v", panicErr)) } }() diff --git a/go/relog/panic.go b/go/relog/panic.go index a7bd513b95..e9333b20ae 100644 --- a/go/relog/panic.go +++ b/go/relog/panic.go @@ -17,32 +17,51 @@ var ( dot = []byte(".") ) -type PanicError interface { +type StackError interface { Error() string String() string StackTrace() string } -type panicError struct { +type stackError struct { err error stackTrace string } -func (e panicError) Error() string { +func (e stackError) Error() string { return e.String() } -func (e panicError) StackTrace() string { +func (e stackError) StackTrace() string { return e.stackTrace } -func (e panicError) String() string { +func (e stackError) String() string { return fmt.Sprintf("%v\n%v", e.err, e.stackTrace) } -func NewPanicError(err error) PanicError { +func Errorf(msg string, args ...interface{}) error { + stack := "" + // See if any arg is already embedding a stack - no need to + // recompute something expensive and make the message unreadable. + for _, arg := range args { + if stackErr, ok := arg.(stackError); ok { + stack = stackErr.stackTrace + break + } + } + + if stack == "" { + // magic 5 trims off just enough stack data to be clear + stack = string(Stack(5)) + } + + return stackError{fmt.Errorf(msg, args...), stack} +} + +func NewPanicError(err error) error { // magic 5 trims off just enough stack data to be clear - return panicError{err, string(Stack(5))} + return stackError{err, string(Stack(5))} } // Taken from runtime/debug.go