123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- package errors
- import (
- "fmt"
- "io"
- "runtime"
- "github.com/pkg/errors"
- )
- func callers() []uintptr {
- var pcs [32]uintptr
- l := runtime.Callers(3, pcs[:])
- return pcs[:l]
- }
- // Error a error with caller stack information
- type Error interface {
- error
- t()
- }
- var _ Error = (*item)(nil)
- var _ fmt.Formatter = (*item)(nil)
- type item struct {
- msg string
- stack []uintptr
- }
- func (i *item) Error() string {
- return i.msg
- }
- func (i *item) t() {}
- // Format used by go.uber.org/zap in Verbose
- func (i *item) Format(s fmt.State, verb rune) {
- io.WriteString(s, i.msg)
- io.WriteString(s, "\n")
- for _, pc := range i.stack {
- fmt.Fprintf(s, "%+v\n", errors.Frame(pc))
- }
- }
- // New create a new error
- func New(msg string) Error {
- return &item{msg: msg, stack: callers()}
- }
- // Errorf create a new error
- func Errorf(format string, args ...any) Error {
- return &item{msg: fmt.Sprintf(format, args...), stack: callers()}
- }
- // Wrap with some extra message into err
- func Wrap(err error, msg string) Error {
- if err == nil {
- return nil
- }
- e, ok := err.(*item)
- if !ok {
- return &item{msg: fmt.Sprintf("%s; %s", msg, err.Error()), stack: callers()}
- }
- e.msg = fmt.Sprintf("%s; %s", msg, e.msg)
- return e
- }
- // Wrapf with some extra message into err
- func Wrapf(err error, format string, args ...any) Error {
- if err == nil {
- return nil
- }
- msg := fmt.Sprintf(format, args...)
- e, ok := err.(*item)
- if !ok {
- return &item{msg: fmt.Sprintf("%s; %s", msg, err.Error()), stack: callers()}
- }
- e.msg = fmt.Sprintf("%s; %s", msg, e.msg)
- return e
- }
- // WithStack add caller stack information
- func WithStack(err error) Error {
- if err == nil {
- return nil
- }
- if e, ok := err.(*item); ok {
- return e
- }
- return &item{msg: err.Error(), stack: callers()}
- }
|