github.com/pachyderm/pachyderm@v1.13.4/src/client/pkg/errors/errors.go (about)

     1  package errors
     2  
     3  import (
     4  	"runtime"
     5  
     6  	"github.com/pkg/errors"
     7  )
     8  
     9  var (
    10  	// New returns an error with the supplied message.
    11  	// New also records the stack trace at the point it was called.
    12  	New = errors.New
    13  	// Errorf formats according to a format specifier and returns the string
    14  	// as a value that satisfies error.
    15  	// Errorf also records the stack trace at the point it was called.
    16  	Errorf = errors.Errorf
    17  	// Unwrap returns the underlying wrapped error if it exists, or nil otherwise.
    18  	Unwrap = errors.Unwrap
    19  	// Is reports whether any error in err's chain matches target. An error is
    20  	// considered to match a target if it is equal to that target or if it
    21  	// implements a method `Is(error) bool` such that `Is(target)` returns true.
    22  	Is = errors.Is
    23  	// Wrap returns an error annotating err with a stack trace
    24  	// at the point Wrap is called, and the supplied message.
    25  	// If err is nil, Wrap returns nil.
    26  	Wrap = errors.Wrap
    27  	// Wrapf returns an error annotating err with a stack trace
    28  	// at the point Wrapf is called, and the format specifier.
    29  	// If err is nil, Wrapf returns nil.
    30  	Wrapf = errors.Wrapf
    31  	// WithStack annotates err with a stack trace at the point WithStack was called.
    32  	// If err is nil, WithStack returns nil.
    33  	WithStack = errors.WithStack
    34  )
    35  
    36  // StackTrace is stack of Frames from innermost (newest) to outermost (oldest).
    37  type StackTrace = errors.StackTrace
    38  
    39  // EnsureStack will add a stack onto the given error only if it does not already
    40  // have a stack. If err is nil, EnsureStack returns nil.
    41  func EnsureStack(err error) error {
    42  	if err == nil {
    43  		return nil
    44  	}
    45  
    46  	if _, ok := err.(StackTracer); ok {
    47  		return err
    48  	}
    49  
    50  	return WithStack(err)
    51  }
    52  
    53  // Frame is the type of a StackFrame, it is an alias for errors.Frame.
    54  type Frame struct{ errors.Frame }
    55  
    56  // Callers returns an errors.StackTrace for the place at which it's called.
    57  func Callers() errors.StackTrace {
    58  	const depth = 32
    59  	var pcs [depth]uintptr
    60  	// 2 skips runtime.Callers and this function
    61  	n := runtime.Callers(2, pcs[:])
    62  	st := make(errors.StackTrace, n)
    63  	for i, pc := range pcs[0:n] {
    64  		st[i] = errors.Frame(pc)
    65  	}
    66  	return st
    67  }
    68  
    69  // StackTracer is an interface for errors that can return stack traces.
    70  // Unfortuantely github.com/pkg/errors makes us define this ourselves rather
    71  // than defining it for us.
    72  type StackTracer interface {
    73  	StackTrace() errors.StackTrace
    74  }
    75  
    76  // ForEachStackFrame calls f on each Frame in the StackTrace contained in err.
    77  // If is a wrapper around another error it is repeatedly unwrapped and f is
    78  // called with frames from the stack of the innermost error.
    79  func ForEachStackFrame(err error, f func(Frame)) {
    80  	var st errors.StackTrace
    81  	for err != nil {
    82  		if err, ok := err.(StackTracer); ok {
    83  			st = err.StackTrace()
    84  		}
    85  		err = errors.Unwrap(err)
    86  	}
    87  	if len(st) > 0 {
    88  		for _, frame := range st {
    89  			f(Frame{frame})
    90  		}
    91  	}
    92  }