Documentation
¶
Overview ¶
Package stacktrace provides optional stack trace support for errx errors.
This package extends errx with stack trace capabilities while keeping the core errx package minimal and zero-dependency. It offers two usage patterns:
Per-error opt-in using Here() as a Classified: err := errx.Wrap("context", cause, ErrNotFound, stacktrace.Here())
Convenience functions that automatically capture traces: err := stacktrace.Wrap("context", cause, ErrNotFound)
Stack traces can be extracted from any error in the chain using Extract():
frames := stacktrace.Extract(err)
for _, frame := range frames {
fmt.Printf("%s:%d %s\n", frame.File, frame.Line, frame.Function)
}
Example (Integration) ¶
Example_integration demonstrates combining stacktrace with other errx features
package main
import (
"errors"
"fmt"
"github.com/go-extras/errx"
"github.com/go-extras/errx/stacktrace"
)
func main() {
var ErrNotFound = errx.NewSentinel("not found")
// Combine stack traces with displayable errors and attributes
displayErr := errx.NewDisplayable("User not found")
attrErr := errx.WithAttrs("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)
}
Output: Error: failed to get user profile: User not found Displayable: User not found Is not found: true Has attributes: true Has stack trace: true
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Classify ¶
func Classify(cause error, classifications ...errx.Classified) error
Classify attaches one or more classifications to an error, automatically capturing a stack trace at the call site.
This is a convenience function equivalent to:
errx.Classify(cause, append(classifications, stacktrace.Here())...)
If cause is nil, Classify returns nil.
Example:
err := stacktrace.Classify(cause, ErrNotFound)
Example ¶
ExampleClassify demonstrates using stacktrace.Classify
package main
import (
"errors"
"fmt"
"github.com/go-extras/errx"
"github.com/go-extras/errx/stacktrace"
)
func main() {
var ErrRetryable = errx.NewSentinel("retryable error")
// stacktrace.Classify adds classification and trace without changing the message
baseErr := errors.New("temporary network failure")
err := stacktrace.Classify(baseErr, ErrRetryable)
// Original message is preserved
fmt.Println(err.Error())
// But classification and trace are added
fmt.Println("Is retryable:", errors.Is(err, ErrRetryable))
fmt.Println("Has trace:", stacktrace.Extract(err) != nil)
}
Output: temporary network failure Is retryable: true Has trace: true
func Here ¶
func Here() errx.Classified
Here captures the current stack trace and returns it as an errx.Classified. It can be used with errx.Wrap() or errx.Classify() to attach stack traces to errors.
The stack trace is captured starting from the caller of Here(), skipping the Here() function itself and the runtime.Callers call.
Example:
err := errx.Wrap("operation failed", cause, ErrNotFound, stacktrace.Here())
The captured stack trace can later be extracted using Extract().
Example ¶
ExampleHere demonstrates using Here() to capture stack traces per-error
package main
import (
"errors"
"fmt"
"github.com/go-extras/errx"
"github.com/go-extras/errx/stacktrace"
)
func main() {
var ErrNotFound = errx.NewSentinel("not found")
// Capture stack trace at this specific error site
baseErr := errors.New("user record missing")
err := errx.Wrap("failed to fetch user", baseErr, ErrNotFound, stacktrace.Here())
// Extract and display the stack trace
frames := stacktrace.Extract(err)
if frames != nil {
fmt.Printf("Stack trace captured: %d frames\n", len(frames))
// In real code, you might log all frames
if len(frames) > 0 {
fmt.Printf("Top frame: %s\n", frames[0].Function)
}
}
}
Output: Stack trace captured: 7 frames Top frame: github.com/go-extras/errx/stacktrace_test.ExampleHere
func Wrap ¶
func Wrap(text string, cause error, classifications ...errx.Classified) error
Wrap wraps an error with additional context text and optional classifications, automatically capturing a stack trace at the call site.
This is a convenience function equivalent to:
errx.Wrap(text, cause, append(classifications, stacktrace.Here())...)
If cause is nil, Wrap returns nil.
Example:
err := stacktrace.Wrap("failed to process order", cause, ErrNotFound)
Example ¶
ExampleWrap demonstrates using stacktrace.Wrap for automatic trace capture
package main
import (
"errors"
"fmt"
"github.com/go-extras/errx"
"github.com/go-extras/errx/stacktrace"
)
func main() {
var ErrDatabase = errx.NewSentinel("database error")
// stacktrace.Wrap automatically captures the stack trace
baseErr := errors.New("connection timeout")
err := stacktrace.Wrap("database query failed", baseErr, ErrDatabase)
// The error works like a normal errx error
fmt.Println(err.Error())
fmt.Println("Is database error:", errors.Is(err, ErrDatabase))
// But also has a stack trace
frames := stacktrace.Extract(err)
fmt.Println("Has stack trace:", frames != nil)
}
Output: database query failed: connection timeout Is database error: true Has stack trace: true
Types ¶
type Frame ¶
type Frame struct {
File string // Full path to the source file
Line int // Line number in the source file
Function string // Fully qualified function name
}
Frame represents a single stack frame with file, line, and function information.
func Extract ¶
Extract returns stack frames from the first traced error found in the error chain. It traverses the entire error chain looking for a traced error and returns its frames.
Returns nil if the error is nil or does not contain any stack trace.
Example:
frames := stacktrace.Extract(err)
if frames != nil {
for _, frame := range frames {
fmt.Printf("%s:%d %s\n", frame.File, frame.Line, frame.Function)
}
}
Example ¶
ExampleExtract demonstrates extracting and formatting stack traces
package main
import (
"errors"
"fmt"
"github.com/go-extras/errx/stacktrace"
)
func main() {
// Create an error with a stack trace
err := stacktrace.Wrap("operation failed", errors.New("base error"))
// Extract the stack trace
frames := stacktrace.Extract(err)
if frames != nil {
fmt.Printf("Stack trace (%d frames):\n", len(frames))
for i, frame := range frames {
if i >= 3 { // Limit output for example
fmt.Println(" ...")
break
}
fmt.Printf(" %s:%d\n", frame.Function, frame.Line)
}
}
}
Output: Stack trace (7 frames): github.com/go-extras/errx/stacktrace_test.ExampleExtract:80 testing.runExample:63 testing.runExamples:41 ...
Example (NoTrace) ¶
ExampleExtract_noTrace demonstrates Extract returning nil for errors without traces
package main
import (
"errors"
"fmt"
"github.com/go-extras/errx/stacktrace"
)
func main() {
// Regular error without stack trace
err := errors.New("simple error")
frames := stacktrace.Extract(err)
fmt.Printf("Stack trace: %v\n", frames)
}
Output: Stack trace: []
func (Frame) String ¶
String returns a formatted representation of the frame.
Example ¶
ExampleFrame_String demonstrates formatting a stack frame
package main
import (
"fmt"
"github.com/go-extras/errx/stacktrace"
)
func main() {
frame := stacktrace.Frame{
File: "/home/user/project/main.go",
Line: 42,
Function: "main.processRequest",
}
fmt.Println(frame.String())
}
Output: /home/user/project/main.go:42 main.processRequest