diff --git a/.vscode/settings.json b/.vscode/settings.json index db2dd0e..03d9e20 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -29,6 +29,7 @@ "go.testExplorer.enable": true, "cSpell.words": [ "djmil", + "Expectf", "gitea", "golangci", "testutil" diff --git a/pkg/result/example_test.go b/pkg/result/example_test.go index 73567a9..3923502 100644 --- a/pkg/result/example_test.go +++ b/pkg/result/example_test.go @@ -100,6 +100,31 @@ func Example_nonErrorPanic() { // non-error panic: unexpected runtime problem } +// Example_expectf shows Expectf for context messages that include runtime +// values — equivalent to Expect(fmt.Sprintf(...)) but more concise. +func Example_expectf() { + port := parsePort("3000").Expectf("read port from arg %d", 1) + fmt.Println(port) + // Output: + // 3000 +} + +// Example_expectfError shows that Expectf annotates the error message with the +// formatted context, just like Expect does. +func Example_expectfError() { + run := func() (err error) { + defer result.Catch(&err) + _ = parsePort("99999").Expectf("arg %d port value", 2) + return nil + } + + if err := run(); err != nil { + fmt.Println("caught:", err) + } + // Output: + // caught: arg 2 port value: parsePort: 99999 out of range +} + // Example_fail shows constructing a failed Expect explicitly, e.g. when a // function detects an error condition before calling any fallible op. func Example_fail() { diff --git a/pkg/result/result.go b/pkg/result/result.go index 475d5bc..6523de4 100644 --- a/pkg/result/result.go +++ b/pkg/result/result.go @@ -59,6 +59,20 @@ func (r Expect[T]) Expect(msg string) T { return r.value } +// Expectf is like [Expect.Expect] but accepts a fmt.Sprintf-style format string +// for the context message. The wrapped error is always appended as ": ". +// +// data := Parse(raw).Expectf("parse user input id=%d", id) +func (r Expect[T]) Expectf(format string, args ...any) T { + if r.err != nil { + panic(&stackError{ + err: fmt.Errorf("%s: %w", fmt.Sprintf(format, args...), r.err), + stack: debug.Stack(), + }) + } + return r.value +} + // Unwrap returns the value and error in the standard Go (value, error) form. // Useful at the boundary where you want to re-join normal error-return code. func (r Expect[T]) Unwrap() (T, error) {