package utils import ( "errors" "fmt" "runtime" "strconv" "strings" ) type WrapErrors struct { message string trace []string } func (e *WrapErrors) Error() string { return e.message } func (e *WrapErrors) StackTrace() string { if e.trace == nil { return "" } return strings.Join(e.trace, "\n") } func ErrorsWrap(err error, message ...string) error { var e *WrapErrors if !errors.As(err, &e) { e = &WrapErrors{} } if len(message) > 0 { e.message = fmt.Sprintf("%v: %v", message[0], err.Error()) } else { e.message = err.Error() } e.trace = append(e.trace, getErrorPath()) return e } func ErrorsWrapF(err error, message string, a ...any) error { var e *WrapErrors if !errors.As(err, &e) { e = &WrapErrors{} } e.message = fmt.Sprintf("%v: %v", fmt.Sprintf(message, a...), err.Error()) e.trace = append(e.trace, getErrorPath()) return e } func getErrorPath() string { _, file, line, _ := runtime.Caller(2) if file == "" { return "unknown" } return file + ":" + strconv.Itoa(line) }