feat(client-go): typed Unauthenticated vs PermissionDenied errors (#198)
Every RPC failure surfaced as a GatewayError with no way to tell a rejected key from a missing scope, though docs/ClientLibrariesDesign.md requires the two be treated distinctly. GatewayError now matches the new sentinels ErrUnauthenticated and ErrPermissionDenied via errors.Is (by gRPC status code only, so it works through the secret-redaction wrapper) and exposes Code(). Tests: errors_auth_test.go — sentinel matching per code, Code(), and a bufconn AcknowledgeAlarm round trip proving the match survives the wire and the password stays redacted (both behavioural tests fail without GatewayError.Is).
This commit is contained in:
@@ -92,7 +92,13 @@ returned subscription owns cancellation and exposes `Close` for deterministic
|
||||
goroutine cleanup. Raw protobuf messages remain available through the
|
||||
`mxgateway` package aliases and the `Raw` helper methods. Typed errors support
|
||||
`errors.As` for `GatewayError`, `CommandError`, and `MxAccessError`; command
|
||||
errors preserve the raw reply.
|
||||
errors preserve the raw reply. Authorization failures are distinct:
|
||||
`errors.Is(err, mxgateway.ErrUnauthenticated)` matches a rejected API key
|
||||
(gRPC `Unauthenticated` — fix the key) and `errors.Is(err,
|
||||
mxgateway.ErrPermissionDenied)` matches a valid key missing a scope or another
|
||||
key's session (gRPC `PermissionDenied` — grant the scope). `GatewayError.Code()`
|
||||
returns the raw gRPC status code. The match reads only the status code, so it
|
||||
works through the credential-redaction wrapper.
|
||||
|
||||
`EnsureMxAccessSuccess` follows COM semantics: only a **negative** HRESULT is a
|
||||
failure, so positive success codes such as `S_FALSE` (1) pass. `StatusSucceeded`
|
||||
|
||||
Reference in New Issue
Block a user