Help us shape the future of Go! Take the 2026 Go Developer Survey

errstack

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 18, 2019 License: MIT Imports: 4 Imported by: 4

README

errstack

A Go library to attach stack call frames to errors.

How to install

go get -u github.com/hnakamur/errstack

Usage

func ExampleStack() {
	level1 := func() error { return os.ErrNotExist }
	level2 := func() error {
		// NOTE: You can use "%s" here just to get call stack frames.
		// However you cannot use errors.Is() or errors.As().
		return errstack.Errorf("level2: %s", level1())
	}
	level3 := func() error { return fmt.Errorf("level3: %w", level2()) }
	err := level3()
	if err != nil {
		fmt.Printf("error: %v\n", err)
		fmt.Printf("is NotExist: %v\n", errors.Is(err, os.ErrNotExist))
		fmt.Printf("stack: %v\n", errstack.Stack(err))
	}
}

func Example_as() {
	level1 := func() error {
		return &os.PathError{Op: "create", Path: "/tmp/foo", Err: os.ErrExist}
	}
	level2 := func() error { return errstack.Errorf("level2: %w", level1()) }
	level3 := func() error { return fmt.Errorf("level3: %w", level2()) }
	err := level3()
	if err != nil {
		fmt.Printf("error: %v\n", err)
		var e2 *os.PathError
		if errors.As(err, &e2) {
			fmt.Printf("pathError: %v\n", e2)
		}
		fmt.Printf("stack: %v\n", errstack.Stack(err))
	}
}

func Example_is() {
	level1 := func() error { return os.ErrNotExist }
	level2 := func() error { return errstack.Errorf("level2: %w", level1()) }
	level3 := func() error { return fmt.Errorf("level3: %w", level2()) }
	err := level3()
	if err != nil {
		fmt.Printf("error: %v\n", err)
		fmt.Printf("is NotExist: %v\n", errors.Is(err, os.ErrNotExist))
		fmt.Printf("stack: %v\n", errstack.Stack(err))
	}
}

License

MIT License

Documentation

Overview

Package errstack provides functions which creates or wraps an error from which you can get call stack frames later at an upper call frame. Functions New and Errorf are a drop-in replacement of errors.New and fmt.Errorf.

Example (As)
package main

import (
	"errors"
	"fmt"
	"os"

	"github.com/hnakamur/errstack"
)

func main() {
	level1 := func() error {
		return &os.PathError{Op: "create", Path: "/tmp/foo", Err: os.ErrExist}
	}
	level2 := func() error { return errstack.Errorf("level2: %w", level1()) }
	level3 := func() error { return fmt.Errorf("level3: %w", level2()) }
	err := level3()
	if err != nil {
		fmt.Printf("error: %v\n", err)
		var e2 *os.PathError
		if errors.As(err, &e2) {
			fmt.Printf("pathError: %v\n", e2)
		}
		fmt.Printf("stack: %v\n", errstack.Stack(err))
	}
}
Example (Is)
package main

import (
	"errors"
	"fmt"
	"os"

	"github.com/hnakamur/errstack"
)

func main() {
	level1 := func() error { return os.ErrNotExist }
	level2 := func() error { return errstack.Errorf("level2: %w", level1()) }
	level3 := func() error { return fmt.Errorf("level3: %w", level2()) }
	err := level3()
	if err != nil {
		fmt.Printf("error: %v\n", err)
		fmt.Printf("is NotExist: %v\n", errors.Is(err, os.ErrNotExist))
		fmt.Printf("stack: %v\n", errstack.Stack(err))
	}
}

Index

Examples

Constants

This section is empty.

Variables

View Source
var MaxFrames = uint32(128)

MaxFrames is the maximum stack frame count used in New and Errorf. Use functions in the sync/atomic package to modify this value.

Functions

func Errorf

func Errorf(format string, a ...interface{}) error

Errorf creates an error with fmt.Errorf and returns a wrapped error.

If any of arguments was created with New or Errorf in this package, then stack call frames are taken from the last argument of those having stack call frames and set to the wrapped error.

If none of arguments are created with New or Errorf in this package, then stack call frames are generated and set to the wrapped error.

The original error returned by errors.New can be obtained by calling Unwrap method of the wrapped error.

Call stack frames can be obtained by calling the Stack function later at the upper call frame.

func New

func New(text string) error

New creates an error with errors.New and returns a wrapped error.

Call stack frames are generated and set to the wrapped error.

The original error returned by errors.New can be obtained by calling Unwrap method of the wrapped error.

Call stack frames can be obtained by calling the Stack function later at the upper call frame.

Types

type Frame

type Frame struct {
	Name string
	Line int
	Path string
}

Frame is a call stack frame.

func Stack

func Stack(err error) []Frame

Stack finds the first error in err's chain that has stack call frames, and returns those if found.

Note you need to build an error chain only with fmt.Errorf with "%w", errstack.Errorf, and errstack.New in order to get stack frames. Otherwise Stack returns nil.

Example
package main

import (
	"errors"
	"fmt"
	"os"

	"github.com/hnakamur/errstack"
)

func main() {
	level1 := func() error { return os.ErrNotExist }
	level2 := func() error {
		// NOTE: You can use "%s" here just to get call stack frames.
		// However you cannot use errors.Is() or errors.As().
		return errstack.Errorf("level2: %s", level1())
	}
	level3 := func() error { return fmt.Errorf("level3: %w", level2()) }
	err := level3()
	if err != nil {
		fmt.Printf("error: %v\n", err)
		fmt.Printf("is NotExist: %v\n", errors.Is(err, os.ErrNotExist))
		fmt.Printf("stack: %v\n", errstack.Stack(err))
	}
}

Jump to

Keyboard shortcuts

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