mirror of
https://github.com/empayre/fleet.git
synced 2024-11-06 17:05:18 +00:00
894fa22c71
This solves #5679 , and also implements #5515, #5509 and lays the ground for #5516 With the introduction of Wrap, Is and As in the standard library, we've now got built-in support for wrapping. On top of that, a common pattern in the community is to define errors tailored to the context of each project while still conforming to the error and Unwrap interfaces (see Upspin, Chromium) The output now includes stack traces and additional info
45 lines
859 B
Go
45 lines
859 B
Go
package ctxerr
|
|
|
|
import (
|
|
"fmt"
|
|
"path/filepath"
|
|
"runtime"
|
|
)
|
|
|
|
const (
|
|
maxDepth = 10 // maximum number of stack frames to record
|
|
)
|
|
|
|
type stackTracer interface {
|
|
List() []string
|
|
}
|
|
|
|
// stack holds a snapshot of program counters.
|
|
type stack []uintptr
|
|
|
|
// newStack captures a stack trace. skip specifies the number of frames to skip from
|
|
// a stack trace. skip=0 records stack.New call as the innermost frame.
|
|
func newStack(skip int) stack {
|
|
pc := make([]uintptr, maxDepth+1)
|
|
pc = pc[:runtime.Callers(skip+2, pc)]
|
|
return stack(pc)
|
|
}
|
|
|
|
// List collects stack traces formatted as strings.
|
|
func (s stack) List() []string {
|
|
var lines []string
|
|
|
|
cf := runtime.CallersFrames(s)
|
|
for {
|
|
f, more := cf.Next()
|
|
line := fmt.Sprintf("%s (%s:%d)", f.Function, filepath.Base(f.File), f.Line)
|
|
lines = append(lines, line)
|
|
|
|
if !more {
|
|
break
|
|
}
|
|
}
|
|
|
|
return lines
|
|
}
|