template/pkg/result/expect_panic.go
djmil 81f5a49cea result: Errw with caller info
- wrap existing errors with context + file:line, newline-separated for readable error chains
- dual mode philosophy: panics + if err != nil
- unify Expect for goexit and panic cases
2026-05-06 23:36:14 +00:00

38 lines
1.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//go:build !result_goexit
// Default error-exit implementation: Expect and Expectf signal failure via
// panic, which is caught by the enclosing result.Go / result.Run goroutine.
//
// Performance: error path ≈ 1.4 µs / ~352 B per failure (goroutine spawn +
// panic + recover). The runtime.Goexit build is about 4× slower (~5.5 µs).
//
// Trade-off: a deferred recover() inside a Go/Run closure that does not
// re-panic unrecognized values will silently swallow a result failure and let
// execution continue as if nothing happened. This follows standard Go practice
// for recover() — always check the type and re-panic anything unrecognized:
//
// defer func() {
// if r := recover(); r != nil {
// if _, ok := r.(MyExpectedType); !ok {
// panic(r) // not ours — let it propagate
// }
// // handle MyExpectedType ...
// }
// }()
//
// If your codebase uses bare recover() inside Go/Run closures, or integrates
// with frameworks that do, opt into the safer runtime.Goexit implementation:
//
// go test -tags result_goexit ./...
// go build -tags result_goexit ./...
package result
// exitGoroutine signals a result failure by panicking with se.
// The panic is caught by the enclosing Async goroutine via recover().
func exitGoroutine(se *stackError) { panic(se) }
// collectGoexitFailure is a no-op in the panic build — failures travel via
// panic/recover, not via the gErrors map.
func collectGoexitFailure() error { return nil }