fix: assign target in SignalError.As instead of only checking its type

errors.As calls SignalError.As when it cannot match the concrete type
directly, e.g. for `var target SignalError; errors.As(err, &target)`.
The previous implementation matched target's type and returned true
but never wrote to it, so callers got a successful errors.As result
with a zero-valued SignalError and no indication the signal was lost.

Add a regression test asserting the target is actually populated.
This commit is contained in:
dualfroz committed 2026-09-04 06:21:22 +02:00
1 parent b0e6917276
commit ae63f3a6f0
2 files changed
+34 -5

No files matched your search

+9 -5
View File
@@ -82,14 +82,18 @@ func (e SignalError) Is(err error) bool {
}
// As fixes a design error in the SignalError type, so that errors.As with the
// literal `&SignalError{}` will return true.
// literal `&SignalError{}` will return true and, per the errors.As contract,
// populate target with the underlying signal.
//
// errors.As requires target to be a non-nil pointer, so the only target type
// that can actually be assigned here is *SignalError.
func (e SignalError) As(target interface{}) bool {
switch target.(type) {
case *SignalError, SignalError:
return true
default:
t, ok := target.(*SignalError)
if !ok {
return false
}
*t = e
return true
}
// ErrSignal is returned by SignalHandler when a signal triggers termination.