chore(deps): consume alkcall 0.7.0 — CONNECTION_CLOSED maps 503
Dependency wave + one wire-surface behavior fix: - bump alkcall 0.6 -> 0.7 (gateway feature unchanged). No code change forced: this crate constructs no ServingConfig (the one 0.7.0 struct-literal break — from_wss keeps the pure-consumer from_connection; opt-in serving remains the review-006 Part C deferred decision), and the CF-006 per-call opener-identity overlay is behavior-only upstream (hub-forwarded WS-ferry opens now resolve the end client's identity, the intended effect) - gateway error table maps CONNECTION_CLOSED -> 503 Service Unavailable: alkcall 0.7.0's CF-007 amendment makes it the eighth protocol code (ADR-016's list is formal at eight); it previously fell to the catch-all 500, misreporting a retryable, provably-undelivered call as a permanent server failure. retryable: true, so the retry_after details path applies on 503. Tests pin the mapping and the Retry-After passthrough - ADR-023 amended: the protocol-code list is eight (ALREADY_EXISTS + CONNECTION_CLOSED rows added to the §3 table, normative rule and call.error code list updated); http-adapters.md six-code references de-staled Verification: cargo test (456 passed), cargo test --all-features (589 passed), clippy -D warnings (default + all-features), fmt --check, cargo doc --no-deps (0 warnings)
This commit is contained in:
1 parent
126fdec243
commit
dbaaa4ec8c
6 files changed
+80
-22
No files matched your search
@@ -4,21 +4,25 @@
|
||||
|
||||
## Status
|
||||
|
||||
Accepted (amended by alknet ADR-049 — protocol-level code list extended to six; alkcall ADR-021)
|
||||
Accepted (amended by alknet ADR-049 — protocol-level code list extended to six; alkcall ADR-021; alkcall 0.7.0 CF-007 — the list is eight: `ALREADY_EXISTS` (alkcall ADR-022, mapped 409 Conflict by review 006 UP-01) and `CONNECTION_CLOSED` (alkcall ADR-016 CF-001, mapped 503 Service Unavailable in this crate's gateway error table))
|
||||
|
||||
## Context
|
||||
|
||||
The `OperationSpec` in the call crate (now alkcall) has `input_schema` and
|
||||
`output_schema` but no `error_schemas`. The `call.error` payload (the alkcall
|
||||
crate's `call-protocol.md`) carries a `code` and `message`, where `code` is
|
||||
one of six infrastructure codes: `NOT_FOUND`, `FORBIDDEN`, `INVALID_INPUT`,
|
||||
`INVALID_OPERATION_TYPE`, `INTERNAL`, `TIMEOUT`.
|
||||
one of eight infrastructure codes: `NOT_FOUND`, `FORBIDDEN`, `INVALID_INPUT`,
|
||||
`INVALID_OPERATION_TYPE`, `INTERNAL`, `TIMEOUT`, `ALREADY_EXISTS`,
|
||||
`CONNECTION_CLOSED`.
|
||||
|
||||
These six codes cover **protocol-level failures** — the call protocol
|
||||
These eight codes cover **protocol-level failures** — the call protocol
|
||||
itself can always fail to find an operation, deny access, reject bad input,
|
||||
reject the wrong dispatch method for the operation type, time out, or hit
|
||||
an internal error. They are emitted by the dispatch machinery (the registry,
|
||||
the adapter), not by operation handlers. `INVALID_OPERATION_TYPE` was added
|
||||
reject the wrong dispatch method for the operation type, time out, hit an
|
||||
internal error, reject an `op/register` collision (`ALREADY_EXISTS`, alkcall
|
||||
ADR-022), or observe a provably-undelivered call (`CONNECTION_CLOSED`,
|
||||
alkcall ADR-016 CF-001 — the only retryable protocol code). They are emitted
|
||||
by the dispatch machinery (the registry, the adapter), not by operation
|
||||
handlers. `INVALID_OPERATION_TYPE` was added
|
||||
by alknet ADR-049 (streaming handler for subscriptions — now alkcall ADR-021;
|
||||
`invoke()` called on a `Sub`, or `invoke_streaming()` on a `Query`/`Mutation`).
|
||||
|
||||
@@ -173,8 +177,8 @@ optional-array convention.
|
||||
|
||||
- `code` — the error code. Either a protocol-level code (`NOT_FOUND`,
|
||||
`FORBIDDEN`, `INVALID_INPUT`, `INVALID_OPERATION_TYPE`, `INTERNAL`,
|
||||
`TIMEOUT`) or an operation-level domain code from `error_schemas` (e.g.,
|
||||
`FILE_NOT_FOUND`, `RATE_LIMITED`).
|
||||
`TIMEOUT`, `ALREADY_EXISTS`, `CONNECTION_CLOSED`) or an operation-level
|
||||
domain code from `error_schemas` (e.g., `FILE_NOT_FOUND`, `RATE_LIMITED`).
|
||||
- `message` — human-readable error message. Unstructured — for logging and
|
||||
debugging, not for programmatic handling. Consumers should switch on
|
||||
`code`, not parse `message`.
|
||||
@@ -190,8 +194,8 @@ optional-array convention.
|
||||
|
||||
### 3. Protocol-level vs operation-level error codes
|
||||
|
||||
The six existing codes are **protocol-level** — emitted by the dispatch
|
||||
machinery, not by handlers:
|
||||
The eight protocol-level codes are **protocol-level** — emitted by the
|
||||
dispatch machinery, not by handlers:
|
||||
|
||||
| Code | Emitted by | Meaning |
|
||||
|------|-----------|---------|
|
||||
@@ -201,6 +205,8 @@ machinery, not by handlers:
|
||||
| `INVALID_OPERATION_TYPE` | Registry / `OperationEnv` | Wrong dispatch path for the operation's type (`invoke()` on a `Sub`, `invoke_streaming()` on a `Query`/`Mutation`, `invoke_sink()` on a `Query`/`Mutation`/`Sub`, or `OperationEnv::invoke()` on a `Sub` during composition — alkcall ADR-021; `Pub` ops dispatch via `invoke_sink()`, alkcall ADR-046) |
|
||||
| `INTERNAL` | Registry / Adapter | Handler panic, unhandled error, connection failure |
|
||||
| `TIMEOUT` | Adapter | Request timed out |
|
||||
| `ALREADY_EXISTS` | Registry / collision gate | `op/register` collision — a peer-announced op may not replace the serving side's own registrations (alkcall ADR-022 G-03) |
|
||||
| `CONNECTION_CLOSED` | Client write path | The `call.requested` frame could not be written — the call is provably undelivered (alkcall ADR-016 CF-001). `retryable: true` — the only protocol code a caller may auto-retry. |
|
||||
|
||||
Operation-level domain codes are emitted by **handlers** — the operation's
|
||||
own logic determines what went wrong. They are declared in `error_schemas`
|
||||
@@ -251,9 +257,9 @@ accordingly.
|
||||
```
|
||||
|
||||
**Normative rule (review #002 W20)**: `from_openapi` must not produce error
|
||||
codes that collide with the six protocol-level codes (`NOT_FOUND`,
|
||||
codes that collide with the protocol-level codes (`NOT_FOUND`,
|
||||
`FORBIDDEN`, `INVALID_INPUT`, `INVALID_OPERATION_TYPE`, `INTERNAL`,
|
||||
`TIMEOUT`). The adapter prefixes
|
||||
`TIMEOUT`, `ALREADY_EXISTS`, `CONNECTION_CLOSED`). The adapter prefixes
|
||||
imported error codes with `HTTP_` and the status number (e.g., `HTTP_404`,
|
||||
`HTTP_429`) to avoid collision. This is a requirement for the adapter, not
|
||||
a naming convention — the `from_openapi` example above was previously shown
|
||||
|
||||
@@ -553,8 +553,9 @@ for the factoring recommendation (thin shared struct, not a trait).
|
||||
`from_openapi` maps OpenAPI non-2xx response status codes to
|
||||
`ErrorDefinition`s (alkcall ADR-016 §5). The normative rule (review
|
||||
#002 W20): `from_openapi` must not produce error codes that collide
|
||||
with the six protocol-level codes (`NOT_FOUND`, `FORBIDDEN`,
|
||||
`INVALID_INPUT`, `INVALID_OPERATION_TYPE`, `INTERNAL`, `TIMEOUT`). The
|
||||
with the protocol-level codes (`NOT_FOUND`, `FORBIDDEN`,
|
||||
`INVALID_INPUT`, `INVALID_OPERATION_TYPE`, `INTERNAL`, `TIMEOUT`,
|
||||
`ALREADY_EXISTS`, `CONNECTION_CLOSED`). The
|
||||
adapter prefixes imported error codes with `HTTP_` and the status
|
||||
number:
|
||||
|
||||
@@ -601,7 +602,7 @@ request-level cap failure (422; GW-16 unified it with the
|
||||
`INVALID_INPUT → 422` mapping — it was hand-rolled as 400 before
|
||||
review-002). `BatchResultEntry.error` references
|
||||
the `BatchError` component (review-002 PRJ-16b): the serialized
|
||||
`CallError` as a oneOf over the six protocol-code envelopes plus a
|
||||
`CallError` as a oneOf over the protocol-code envelopes plus a
|
||||
generic arm carrying the operation-declared codes. See alkcall ADR-016.
|
||||
|
||||
## Why
|
||||
|
||||
Reference in new issue
Block a user