stacktrace

package module
v1.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 9, 2025 License: Apache-2.0 Imports: 5 Imported by: 1

README

stacktrace/v2

Note: This is the documentation for v2 of the stacktrace module.
For v1 documentation, see README.v1.md.

Package stacktrace provides utilities for capturing and inspecting stack traces associated with errors.

Go Reference Go Report Card

Features

  • Wraps errors with a single stack trace
    • Typically, a single error chain contains at most one stack trace
  • Extracts the stack trace from an error

Usage

Trace

The most basic way to create an error with a stack trace is to use the Trace function:

err := stacktrace.Trace(os.Chdir(target))

There are Trace2, Trace3, and Trace4: These are overloads of Trace that return the given values unchanged if err is nil. If err is not nil, it wraps err with stack trace information before returning.

file, err := stacktrace.Trace2(os.Open(file))
New and Errorf

For convenience, you can use New and Errorf as drop-in replacements for errors.New and fmt.Errorf:

err := stacktrace.New("some error")
err := stacktrace.Errorf("some error: %w", originalErr)

Extracting Stack Trace Information

As a string

To get a formatted string representation of stack trace information from an error:

// Get as a string.
// This is equivalent to calling `err.Error()`
// if `err` does not contain stack trace information.
// `s` is an empty string if `err` is nil.
s := stacktrace.Format(err)

Use Format. For example, the s contains multiline string like below:

chdir /no/such/dir: no such file or directory (run.go:10 main.run)
        example.com/hello/run.go:10 main.run
        example.com/hello/main.go:11 main.main
As a DebugInfo

To extract stack trace information from an error:

// Get as a DebugInfo instance
info := stacktrace.GetDebugInfo(err)

The DebugInfo type is compatible with google.golang.org/genproto/googleapis/rpc/errdetails.DebugInfo.

For example, the info contains information like below:

{
  "detail": "chdir /no/such/dir: no such file or directory (run.go:10 main.run)",
  "stack_entries": [
    "example.com/hello/run.go:10 main.run",
    "example.com/hello/main.go:11 main.main"
  ]
}
Other ways

Alternatively, you can use errors.As to extract the Error instance from an error chain. CallersFrames is available in Go 1.23 or later.

var info *stacktrace.Error
if errors.As(err, &info) {
	for frame := range stacktrace.CallersFrames(info.Callers) {
		_, _ = frame.File, frame.Line
	}
}

Performance Considerations

Adding stack traces to errors involves some overhead. In performance-critical sections, consider using traditional error handling and adding stack traces at higher levels of your application.

Documentation

Overview

Package stacktrace provides enhanced error handling capabilities with stack trace information.

It offers a way to wrap errors with stack traces, extract stack information from error chains, and format error messages with detailed stack information.

Example
package main

import (
	"encoding/json"
	"fmt"
	"os"

	"github.com/goaux/stacktrace"
)

func main() {
	err := doSomethingRisky()
	if err != nil {
		fmt.Println("An error occurred:")
		fmt.Println("error: " + stacktrace.Format(err))

		fmt.Println("\nJSON representation of the error:")
		dumpJSON, _ := json.MarshalIndent(stacktrace.Dump(err), "", "  ")
		fmt.Println(string(dumpJSON))
	}
}

func doSomethingRisky() error {
	err := openNonExistentFile()
	if err != nil {
		return stacktrace.With(err, stacktrace.Skip(1))
	}
	return nil
}

func openNonExistentFile() error {
	_, err := os.Open("non_existent_file.txt")
	if err != nil {
		return stacktrace.Errorf("failed to open file: %w", err)
	}
	return nil
}
Output:

Index

Examples

Constants

View Source
const DefaultLimit = 32

DefaultLimit is the default depth for retrieving stack frames.

Variables

View Source
var Always always

Always is an Option that specifies always including a new *Error in the error chain, even if the chain already contains a *Error.

The default behavior of Wrap is to return the cause if the chain already contains a *Error, and to create a new *Error with the cause and stack frames otherwise.

When this option is set, Wrap always creates a new *Error with the cause and stack frames.

see

stacktrace.Always.Errorf(...)
View Source
var Single single

Single is an Option that cancels Always and reverts to default behavior.

Functions

func Errorf

func Errorf(format string, a ...any) error

Errorf creates a new error using fmt.Errorf and wraps it with stack trace information.

It's meant to be used as a replacement for fmt.Errorf. To specify options, use With(fmt.Errorf(...), options...) instead.

see

stacktrace.Always.Errorf(...)

func Format

func Format(err error) string

Format returns a string representation of the error, including stack trace information if available.

If err is nil, it returns an empty string. If err's chain doesn't contain any *Error, it returns err.Error().

func Frames

func Frames(frames []uintptr) []string

Frames converts a slice of stack frame pointers to a slice of formatted strings.

Each string in the returned slice has the format "<file>:<line> <function>".

func New

func New(text string, options ...Option) error

New creates a new error with the given text and wraps it with stack trace information.

It's meant to be used as a replacement for errors.New. Options can be provided to customize the behavior.

func With

func With(cause error, options ...Option) error

With wraps the given cause error with stack trace information.

If cause is nil, it returns nil. Options can be provided to customize the behavior.

Types

type Error

type Error struct {
	Cause  error
	Frames []uintptr
}

Error represents an error with an associated cause and stack frames.

func Extract

func Extract(err error) []*Error

Extract returns a slice of *Error from the error chain of err.

It traverses the error chain and collects all *Error instances. The returned slice is ordered such that the first added *Error (i.e., the one closest to the root cause) is at index 0, and the most recently added *Error (i.e., the one furthest from the root cause) is at the last index. This means that the stack trace added first in the error chain will be at the beginning of the returned slice. If err is nil or contains no *Error, an empty slice is returned.

func (Error) Error

func (err Error) Error() string

Error returns the error message of the underlying cause.

It implements the error interface.

func (Error) StackTrace added in v1.1.0

func (err Error) StackTrace() []uintptr

StackTrace returns a slice of program counters representing the call stack.

func (Error) Unwrap

func (err Error) Unwrap() error

Unwrap returns the underlying cause of the error.

It allows Error to work with errors.Unwrap.

type Option

type Option interface {
	// contains filtered or unexported methods
}

Option is the type for options that modify the behavior of With.

func Limit

func Limit(n int) Option

Limit returns an Option that limits the depth of the retrieved stack.

func Skip

func Skip(n int) Option

Skip returns an Option that adjusts the starting position of the retrieved stack.

type StackDump

type StackDump struct {
	// Error stores the result of err.Error().
	Error string `json:"error,omitempty"`

	// Traces stores the result of Extract(err) converted to StackTrace.
	Traces []StackTrace `json:"traces,omitempty"`
}

StackDump represents a structured version of an error chain containing *Error.

func Dump

func Dump(err error) StackDump

Dump converts the result of Extract(err) to a StackDump. It provides a structured representation equivalent to what Format returns as a string. Dump returns the zero value if err is nil.

type StackTrace

type StackTrace struct {
	// Detail stores the result of Error.Cause.Error().
	Detail string `json:"detail,omitempty"`

	// StackEntries stores the result of Frames(Error.Frames).
	StackEntries []string `json:"stack_entries,omitempty"`
}

StackTrace represents a structured version of a single *Error in an error chain.

type StackTracer added in v1.1.0

type StackTracer interface {
	// StackTracer extends the error interface.
	error

	// StackTrace returns a slice of program counters representing the call stack.
	StackTrace() []uintptr
}

StackTracer represents an error that provides stack trace information.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL