diff --git a/loggers/cli/cli.go b/loggers/cli/cli.go index d980250..bb673b0 100644 --- a/loggers/cli/cli.go +++ b/loggers/cli/cli.go @@ -69,25 +69,44 @@ func (h *Handler) HandleLog(e *log.Entry) error { continue } + var br = color2.New(color2.Bold, color2.FgRed) if err, ok := e.Fields.Get("error").(error); ok { - var br = color2.New(color2.Bold, color2.FgRed) - - if e, ok := errors.Cause(err).(tracer); ok { - st := e.StackTrace() - - l := len(st) - if l > 5 { - l = 5 - } - - fmt.Fprintf(h.Writer, "\n%s%+v\n\n", br.Sprintf("Stacktrace:"), st[0:l]) - } else { - fmt.Fprintf(h.Writer, "\n%s\n%+v\n\n", br.Sprintf("Stacktrace:"), err) - } + fmt.Fprintf(h.Writer, "\n%s%+v\n\n", br.Sprintf("Stacktrace:"), getErrorStack(err, false)) } else { - fmt.Printf("\n\nINVALID ERROR\n\n") + fmt.Fprintf(h.Writer, "\n%s%+v\n\n", br.Sprintf("Invalid Error:"), err) } } return nil } + +func getErrorStack(err error, i bool) errors.StackTrace { + e, ok := errors.Cause(err).(tracer) + if !ok { + if i { + // Just abort out of this and return a stacktrace leading up to this point. It isn't perfect + // but it'll at least include what function lead to this being called which we can then handle. + return errors.Wrap(err, "failed to generate stacktrace for caught error").(tracer).StackTrace() + } + + return getErrorStack(errors.New(err.Error()), true) + } + + st := e.StackTrace() + + l := len(st) + // If this was an internal stack generation we're going to skip over the top four items in the stack + // trace since they'll point to the error that was generated by this function. + f := 0 + if i { + f = 4 + } + + if i && l > 9 { + l = 9 + } else if !i && l > 5 { + l = 5 + } + + return st[f:l] +}