Optional stack trace support for errx errors.
The stacktrace package extends errx with stack trace capabilities while keeping the core errx package minimal and zero-dependency. It provides two usage patterns:
- Per-error opt-in using
Here()as aClassified - Automatic capture using
stacktrace.Wrap()andstacktrace.Classify()
go get github.com/go-extras/errx/stacktrace@latestUse Here() to capture stack traces only where needed:
import (
"github.com/go-extras/errx"
"github.com/go-extras/errx/stacktrace"
)
var ErrNotFound = errx.NewSentinel("not found")
// Capture stack trace at this specific error site
err := errx.Wrap("operation failed", cause, ErrNotFound, stacktrace.Here())Use stacktrace.Wrap() or stacktrace.Classify() for automatic trace capture:
// Automatically captures stack trace
err := stacktrace.Wrap("operation failed", cause, ErrNotFound)
// Or with Classify
err := stacktrace.Classify(cause, ErrRetryable)Extract and use stack traces from any error in the chain:
frames := stacktrace.Extract(err)
if frames != nil {
for _, frame := range frames {
fmt.Printf("%s:%d %s\n", frame.File, frame.Line, frame.Function)
}
}Stack traces work seamlessly with all errx features:
var ErrNotFound = errx.NewSentinel("not found")
// Combine stack traces with displayable errors and attributes
displayErr := errx.NewDisplayable("User not found")
attrErr := errx.Attrs("user_id", "12345", "action", "fetch")
err := stacktrace.Wrap("failed to get user profile",
errx.Classify(displayErr, ErrNotFound, attrErr))
// All features work together
fmt.Println("Error:", err.Error())
fmt.Println("Displayable:", errx.DisplayText(err))
fmt.Println("Is not found:", errors.Is(err, ErrNotFound))
fmt.Println("Has attributes:", errx.HasAttrs(err))
fmt.Println("Has stack trace:", stacktrace.Extract(err) != nil)Here() errx.Classified- Captures the current stack trace as a ClassifiedExtract(err error) []Frame- Extracts stack frames from an error chainWrap(text string, cause error, classifications ...errx.Classified) error- Wraps with automatic traceClassify(cause error, classifications ...errx.Classified) error- Classifies with automatic trace
Frame- Represents a single stack frame withFile,Line, andFunctionfields
Stack trace capture has a small performance cost (~2-10µs per capture):
- Uses
runtime.Callersto walk the stack - Allocates a slice for program counters
- Frame resolution is done lazily on
Extract()
Recommendations:
- Use per-error opt-in (
Here()) in hot paths - Use automatic capture (
stacktrace.Wrap()) in application code - Libraries should use core
errx; applications add traces as needed
This package follows Option 6 from the errx tracing design:
- Core stays minimal:
errxremains zero-dependency and fast - Opt-in granularity: Choose per-error or blanket trace capture
- Composable: Traces are just another
Classified, fitting existing patterns - Library-friendly: Libraries use
errxcore; applications add tracing where needed
See the package documentation for more examples.
MIT License - see the LICENSE file for details.