package errors import ( "context" "fmt" "runtime" ) // WrapContextError wraps a context error with detailed information about the operation // that failed, including the function name, parameters, and call location. // // Example usage: // // if ctx.Err() != nil { // return errors.WrapContextError(ctx.Err(), "fetchTransactionReceipt", // map[string]interface{}{ // "txHash": txHash.Hex(), // "attempt": attempt, // "maxRetries": maxRetries, // }) // } func WrapContextError(err error, functionName string, params map[string]interface{}) error { if err == nil { return nil } // Get caller information pc, file, line, ok := runtime.Caller(1) funcName := "unknown" if ok { fn := runtime.FuncForPC(pc) if fn != nil { funcName = fn.Name() } } // Build detailed error message msg := fmt.Sprintf("context error in %s", functionName) // Add parameters if len(params) > 0 { msg += " [" first := true for key, value := range params { if !first { msg += ", " } msg += fmt.Sprintf("%s=%v", key, value) first = false } msg += "]" } // Add caller location if ok { msg += fmt.Sprintf(" (at %s:%d in %s)", file, line, funcName) } // Determine context error type var errType string switch err { case context.Canceled: errType = "context canceled" case context.DeadlineExceeded: errType = "context deadline exceeded" default: errType = fmt.Sprintf("%v", err) } return fmt.Errorf("%s: %s", msg, errType) } // WrapContextErrorf wraps a context error with a formatted message and parameters func WrapContextErrorf(err error, format string, args ...interface{}) error { if err == nil { return nil } // Get caller information pc, file, line, ok := runtime.Caller(1) funcName := "unknown" if ok { fn := runtime.FuncForPC(pc) if fn != nil { funcName = fn.Name() } } msg := fmt.Sprintf(format, args...) // Add caller location if ok { msg += fmt.Sprintf(" (at %s:%d in %s)", file, line, funcName) } // Determine context error type var errType string switch err { case context.Canceled: errType = "context canceled" case context.DeadlineExceeded: errType = "context deadline exceeded" default: errType = fmt.Sprintf("%v", err) } return fmt.Errorf("%s: %s", msg, errType) }