e967e85973
MxAccessError.Unwrap returned e.Command directly; on the HRESULT-only path Command is a nil *CommandError, so Unwrap returned a non-nil error wrapping a typed nil and errors.As bound a nil *CommandError. Unwrap now returns an untyped nil when Command is nil. Added errors_test.go regression coverage for the HRESULT-only and populated-Command paths. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
43 lines
1.4 KiB
Go
43 lines
1.4 KiB
Go
package mxgateway
|
|
|
|
import (
|
|
"errors"
|
|
"testing"
|
|
)
|
|
|
|
// TestMxAccessErrorUnwrapHResultPathNoTypedNilCommandError reproduces
|
|
// Client.Go-001: an MxAccessError built via the HRESULT / MxStatusProxy path
|
|
// leaves Command nil. Unwrap must not hand back a typed-nil *CommandError,
|
|
// because errors.As would then succeed while binding a nil pointer and a
|
|
// caller dereferencing it would panic.
|
|
func TestMxAccessErrorUnwrapHResultPathNoTypedNilCommandError(t *testing.T) {
|
|
hresult := int32(-2147467259) // 0x80004005, a failing HRESULT.
|
|
reply := &MxCommandReply{Hresult: &hresult}
|
|
|
|
err := EnsureMxAccessSuccess("invoke", reply)
|
|
if err == nil {
|
|
t.Fatal("expected MxAccessError for a failing HRESULT, got nil")
|
|
}
|
|
|
|
var ce *CommandError
|
|
if errors.As(err, &ce) {
|
|
t.Fatalf("errors.As bound *CommandError from an HRESULT-only MxAccessError (ce=%v); "+
|
|
"a caller dereferencing ce.Status would panic", ce)
|
|
}
|
|
}
|
|
|
|
// TestMxAccessErrorUnwrapPopulatedCommand confirms the non-nil Command path
|
|
// still unwraps to the wrapped *CommandError.
|
|
func TestMxAccessErrorUnwrapPopulatedCommand(t *testing.T) {
|
|
command := &CommandError{Op: "invoke"}
|
|
err := &MxAccessError{Command: command}
|
|
|
|
var ce *CommandError
|
|
if !errors.As(err, &ce) {
|
|
t.Fatal("errors.As failed to bind the populated *CommandError")
|
|
}
|
|
if ce != command {
|
|
t.Fatalf("errors.As bound an unexpected *CommandError: got %v want %v", ce, command)
|
|
}
|
|
}
|