2026-03-03 17:09:44 -05:00
|
|
|
package errors
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"errors"
|
|
|
|
|
"fmt"
|
|
|
|
|
"path"
|
|
|
|
|
"runtime"
|
|
|
|
|
"slices"
|
|
|
|
|
"strings"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// wrap stdlib errors functions to make it easier to import this package as a replacement
|
|
|
|
|
var As = errors.As
|
|
|
|
|
var Is = errors.Is
|
2026-03-03 17:24:49 -05:00
|
|
|
var Join = errors.Join
|
2026-03-03 17:09:44 -05:00
|
|
|
var New = errors.New
|
|
|
|
|
|
|
|
|
|
var ErrCommandNoArgs = New("this command does not take any arguments")
|
|
|
|
|
var ErrUnsupportedPlatform = New("unsupported platform")
|
|
|
|
|
|
|
|
|
|
func WithStack(err error) error {
|
|
|
|
|
stack := []string{}
|
|
|
|
|
pcs := make([]uintptr, 32)
|
|
|
|
|
runtime.Callers(2, pcs)
|
|
|
|
|
frames := runtime.CallersFrames(pcs)
|
|
|
|
|
for {
|
|
|
|
|
frame, more := frames.Next()
|
|
|
|
|
if !strings.HasPrefix(frame.Function, "runtime.") {
|
|
|
|
|
stack = append(stack, fmt.Sprintf("%s(%s:%d)", frame.Function, path.Base(frame.File), frame.Line))
|
|
|
|
|
}
|
|
|
|
|
if !more {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
slices.Reverse(stack)
|
|
|
|
|
return fmt.Errorf("%w at %s", err, strings.Join(stack, "->"))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func WithMessage(err error, msg string) error {
|
|
|
|
|
if err == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
return fmt.Errorf("%s: %w", msg, err)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func WithMessagef(err error, format string, args ...any) error {
|
|
|
|
|
if err == nil {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
return fmt.Errorf("%s: %w", fmt.Sprintf(format, args...), err)
|
|
|
|
|
}
|