| package errorsx | |
| import ( | |
| "errors" | |
| "fmt" | |
| ) | |
| // WithPrefix annotates an error with a prefix. | |
| func WithPrefix(err error, prefix string) error { | |
| if err == nil { | |
| return nil | |
| } | |
| type unwrapper interface { | |
| Unwrap() []error | |
| } | |
| // Deliberately checking for the unwrapper interface instead of the errors.Is function. | |
| // We only want to check the top-level error otherwise we may accidentally drop other wrappers from the error chain. | |
| e, ok := err.(unwrapper) | |
| if !ok { | |
| return fmt.Errorf("%s: %w", prefix, err) | |
| } | |
| errs := e.Unwrap() | |
| for i, err := range errs { | |
| errs[i] = WithPrefix(err, prefix) | |
| } | |
| return errors.Join(errs...) | |
| } | |
| var _ error = (*warnError)(nil) | |
| type warnError struct { | |
| Err error | |
| } | |
| func (w *warnError) Error() string { | |
| return w.Err.Error() | |
| } | |
| func (w *warnError) Unwrap() error { | |
| return w.Err | |
| } | |
| func NewWarnError(err error) error { | |
| if err == nil { | |
| return nil | |
| } | |
| return &warnError{Err: err} | |
| } | |