Documentation
¶
Overview ¶
Package stacked attaches stack traces to errors. Wrap captures the call stack at its invocation site and stores it alongside the error; StackTrace retrieves the frames later. Wrapped errors satisfy errors.Is, errors.As, and errors.Unwrap, so they compose with standard error handling.
For the captured frames to point at where an error actually originated rather than at intermediate forwarders, wrap errors at their source — the call or expression that produces them:
err := stacked.Wrap(os.Chdir("/"))
Wrapping is idempotent: Wrap returns nil, already-wrapped errors, and ignored errors unchanged, so the first wrap wins. io.EOF is ignored by default; register additional ignored errors with Ignore or IgnoreFunc.
Recover converts panics and runtime.Goexit into stacked errors.
Index ¶
- Variables
- func Ignore(err error)
- func IgnoreFunc(ignoreFunc func(error) bool)
- func Recover(f func(), onPanic func(err error), exitOnPanic bool)
- func Wrap(err error) error
- func Wrap2[T any](v T, err error) (T, error)
- func Wrap3[T1, T2 any](v1 T1, v2 T2, err error) (T1, T2, error)
- func Wrap4[T1, T2, T3 any](v1 T1, v2 T2, v3 T3, err error) (T1, T2, T3, error)
- func Wrap5[T1, T2, T3, T4 any](v1 T1, v2 T2, v3 T3, v4 T4, err error) (T1, T2, T3, T4, error)
- func WrapPull(err error, ok bool) (error, bool)
- func WrapPull2[T any](v T, err error, ok bool) (T, error, bool)
- func WrapSeq(seq iter.Seq[error]) iter.Seq[error]
- func WrapSeq2[T any](seq iter.Seq2[T, error]) iter.Seq2[T, error]
- type Error
- type StackFrame
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNilPanicValue is reported by [Recover] when the recovered panic value // is nil. On Go ≥ 1.21 this is unreachable without GODEBUG=panicnil=1; the // runtime converts panic(nil) into a *[runtime.PanicNilError] instead. ErrNilPanicValue = errors.New("panic with nil value") // ErrGoexitCalled is reported by [Recover] when its function exits via // [runtime.Goexit]. ErrGoexitCalled = errors.New("runtime.Goexit called") )
Functions ¶
func Ignore ¶ added in v0.7.0
func Ignore(err error)
Ignore registers err so future Wrap, WrapSeq, or WrapPull calls return it unchanged instead of attaching a stack trace. Calls are deduplicated by identity; registering the same error twice is a no-op. io.EOF is registered by default.
func IgnoreFunc ¶ added in v0.7.0
IgnoreFunc registers a predicate consulted alongside Ignore's list. If any registered predicate returns true for an error, the error is left unwrapped.
func Recover ¶
Recover runs f and routes its outcome through onPanic:
- f returns normally: onPanic is not called.
- f panics: onPanic is called with a *Error whose Err is the panic value (if it satisfies error) or fmt.Errorf("%v", value) otherwise, and whose stack trace points at the panic site.
- f exits via runtime.Goexit: onPanic is called with a *Error wrapping ErrGoexitCalled.
onPanic may be nil. If exitOnPanic is true, Recover calls os.Exit(1) after onPanic returns.
Example ¶
package main
import (
"fmt"
"github.com/tbeati/stacked"
)
func main() {
stacked.Recover(
func() {
panic("something went wrong")
},
func(err error) {
fmt.Println(err)
stackTrace := stacked.StackTrace(err)
_ = stackTrace // stack trace at the panic site
},
false,
)
}
Output: something went wrong
func Wrap ¶
Wrap attaches a stack trace to err captured at this call site. It returns nil unchanged, ignored errors unchanged, and already-wrapped errors unchanged (the first wrap wins). Use the arity-matching variant — Wrap2, Wrap3, Wrap4, Wrap5 — when wrapping the return of a function that produces additional values.
func Wrap3 ¶ added in v0.5.0
Wrap3 is the three-value form of Wrap; v1 and v2 are returned unchanged.
func Wrap4 ¶ added in v0.7.0
Wrap4 is the four-value form of Wrap; v1, v2, and v3 are returned unchanged.
func Wrap5 ¶ added in v0.7.0
Wrap5 is the five-value form of Wrap; v1, v2, v3, and v4 are returned unchanged.
func WrapPull ¶ added in v0.7.0
WrapPull wraps an error returned from an iter.Pull-style next function with a stack trace captured at the pull site. Already-wrapped errors and ignored errors pass through unchanged. The ok value is returned unchanged.
func WrapPull2 ¶ added in v0.7.0
WrapPull2 is the three-value form of WrapPull; v is returned unchanged.
Types ¶
type Error ¶
type Error struct {
Err error
StackTrace []StackFrame
// contains filtered or unexported fields
}
Error wraps an underlying error together with a stack trace captured at the wrap site. Recover one from an arbitrary error via errors.As or errors.AsType, or call StackTrace for the frames directly.
type StackFrame ¶
type StackFrame struct {
Function string `json:"function"`
File string `json:"file"`
Line int `json:"line"`
}
StackFrame is a single entry in a captured stack trace.
func StackTrace ¶
func StackTrace(err error) []StackFrame
StackTrace returns the captured frames if err is or wraps a *Error, otherwise nil.