fleet/server/contexts/ctxerr/stack.go
Roberto Dip 894fa22c71
implement a thin wrapper around stdlib errors (#5733)
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
2022-05-18 11:47:55 -03:00

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
}