WrapWithStackSkip creates a new [WrappedError] with the given error and options. It the first stackSkip frames from the call stack. If the provided error already an [Error], it clones its context and applies the new options to it. If the provided error is already an [WrappedError], it rewraps its
(err error, stackSkip int, opts ...Option)
| 43 | // If the provided error is already an [WrappedError], it rewraps its inner error |
| 44 | // to avoid double wrapping. |
| 45 | func WrapWithStackSkip(err error, stackSkip int, opts ...Option) Error { |
| 46 | if err == nil { |
| 47 | return nil |
| 48 | } |
| 49 | |
| 50 | var ec *ErrorContext |
| 51 | |
| 52 | // Check if the error already has context |
| 53 | if ewc, ok := err.(Error); ok { |
| 54 | // If the error already has context and no new options are provided, |
| 55 | // we don't need to wrap it again and can return it as is. |
| 56 | if len(opts) == 0 { |
| 57 | return ewc |
| 58 | } |
| 59 | |
| 60 | // Clone the existing context to avoid modifying the original one |
| 61 | // and apply new options |
| 62 | ec = ewc.CloneErrorContext(opts...) |
| 63 | |
| 64 | // If the error is already an WrappedError, get its inner error |
| 65 | // to avoid double wrapping |
| 66 | if ew, ok := err.(*WrappedError); ok { |
| 67 | err = ew.Unwrap() |
| 68 | } |
| 69 | } else { |
| 70 | // If the error does not have context, create a new one |
| 71 | ec = newErrorContext(stackSkip+1, opts...) |
| 72 | } |
| 73 | |
| 74 | return &WrappedError{ |
| 75 | error: err, |
| 76 | ErrorContext: ec, |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | // Error returns the error message with prefix if set. |
| 81 | func (e *WrappedError) Error() string { |