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))
}
}
Output:
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))
}
}
Output:
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
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 ¶
Errorf creates an error with fmt.Errorf and returns a wrapped error.
If any of arguments has LV() []string method, then the error is wrapped with the result from the last argument which has LV() []string method. That result can be obtained later with the LV function.
If any of arguments has the Stack() []Frame method, 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 has the Stack() []Frame method, then stack call frames are generated and set to the wrapped error.
The original error returned by fmt.Errorf 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 LV ¶ added in v0.1.2
LV get the pairs of labels and values of the first error which has LV() []string method in the err's chain.
func New ¶
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.
func WithLV ¶ added in v0.1.2
WithLV wraps the error and attach pairs of labels and values to the wrapped error.
If any of the err's chain has the LV() []string method, the pairs of labeld and values of the wrapped error will be the concatination of the pairs of labels and values of the first error which has LV() []string method and the lv argument.
The pairs of labels and values can be get calling the LV function to the wrapped error.
Types ¶
type Frame ¶
Frame is a call stack frame.
func Stack ¶
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))
}
}
Output: