2019-01-03 19:04:23 +00:00
|
|
|
package pkgerrors
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
|
|
|
StackSourceFileName = "source"
|
|
|
|
StackSourceLineName = "line"
|
|
|
|
StackSourceFunctionName = "func"
|
|
|
|
)
|
|
|
|
|
|
|
|
type state struct {
|
|
|
|
b []byte
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write implement fmt.Formatter interface.
|
|
|
|
func (s *state) Write(b []byte) (n int, err error) {
|
|
|
|
s.b = b
|
|
|
|
return len(b), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Width implement fmt.Formatter interface.
|
|
|
|
func (s *state) Width() (wid int, ok bool) {
|
|
|
|
return 0, false
|
|
|
|
}
|
|
|
|
|
|
|
|
// Precision implement fmt.Formatter interface.
|
|
|
|
func (s *state) Precision() (prec int, ok bool) {
|
|
|
|
return 0, false
|
|
|
|
}
|
|
|
|
|
|
|
|
// Flag implement fmt.Formatter interface.
|
|
|
|
func (s *state) Flag(c int) bool {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func frameField(f errors.Frame, s *state, c rune) string {
|
|
|
|
f.Format(s, c)
|
|
|
|
return string(s.b)
|
|
|
|
}
|
|
|
|
|
|
|
|
// MarshalStack implements pkg/errors stack trace marshaling.
|
|
|
|
//
|
2023-07-17 16:43:17 +00:00
|
|
|
// zlog.ErrorStackMarshaler = MarshalStack
|
2019-01-03 19:04:23 +00:00
|
|
|
func MarshalStack(err error) interface{} {
|
|
|
|
type stackTracer interface {
|
|
|
|
StackTrace() errors.StackTrace
|
|
|
|
}
|
2023-05-15 12:07:32 +00:00
|
|
|
var sterr stackTracer
|
|
|
|
var ok bool
|
|
|
|
for err != nil {
|
|
|
|
sterr, ok = err.(stackTracer)
|
|
|
|
if ok {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
|
|
|
|
u, ok := err.(interface {
|
|
|
|
Unwrap() error
|
|
|
|
})
|
|
|
|
if !ok {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
err = u.Unwrap()
|
|
|
|
}
|
|
|
|
if sterr == nil {
|
2019-01-03 19:04:23 +00:00
|
|
|
return nil
|
|
|
|
}
|
2023-05-15 12:07:32 +00:00
|
|
|
|
2019-01-03 19:04:23 +00:00
|
|
|
st := sterr.StackTrace()
|
|
|
|
s := &state{}
|
|
|
|
out := make([]map[string]string, 0, len(st))
|
|
|
|
for _, frame := range st {
|
|
|
|
out = append(out, map[string]string{
|
|
|
|
StackSourceFileName: frameField(frame, s, 's'),
|
|
|
|
StackSourceLineName: frameField(frame, s, 'd'),
|
|
|
|
StackSourceFunctionName: frameField(frame, s, 'n'),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return out
|
|
|
|
}
|