fix(client): classify discover outcome at source, not at the error type (#1133)
`ClientLifecycleMode::Auto` only fell back from `server/discover` on `-32601`, so legacy servers that reject the probe with other codes (`-32600`, `-32602`, implementation-defined errors) failed to connect even though `initialize` would have succeeded. The previous attempt (indicates_legacy_server) classified the failure after the fact by reverse-engineering the error type. This rewrite moves the classification into `discover_startup` itself, where the full context (request id, response correlation, transport state) is still available. `discover_startup` now returns `DiscoverOutcome`: `Modern` on success, `Legacy(error)` when the probe received a complete, correlated JSON-RPC error whose code is not a modern-era rejection. Every other failure becomes `Err`, so `Auto` simply matches the outcome — no methods on `ClientInitializeError`, no downcast, no transport-specific types leaking into the generic lifecycle layer. Additional fixes that fall out naturally: - Response correlation is now checked in `expect_response` for both success and error branches. Previously error responses skipped id correlation entirely. A new `UncorrelatedErrorResponse` variant surfaces responses that cannot be tied to the request. - When both discover and the legacy fallback fail, a `LegacyFallbackFailed` compound error preserves both phases instead of discarding the discover error. Fixes #1040.
This commit is contained in:
parent
02c62aef2e
commit
22be2cc5ad
1 changed files with 468 additions and 45 deletions
|
|
@ -125,11 +125,18 @@ async fn test_client_init_handles_jsonrpc_error() {
|
|||
});
|
||||
|
||||
tokio::spawn(async move {
|
||||
let _init_request = server.receive().await;
|
||||
let request = server.receive().await;
|
||||
// Echo the request's own id back on the error so it correlates: an
|
||||
// uncorrelated id would surface as `UncorrelatedErrorResponse`
|
||||
// instead of the `JsonRpcError` this test exercises.
|
||||
let request_id = request
|
||||
.and_then(|message| message.into_request())
|
||||
.map(|(_, id)| id)
|
||||
.expect("client sent an initialize request");
|
||||
|
||||
let error_msg = ServerJsonRpcMessage::Error(JsonRpcError {
|
||||
jsonrpc: JsonRpcVersion2_0,
|
||||
id: Some(RequestId::Number(1)),
|
||||
id: Some(request_id),
|
||||
error: ErrorData {
|
||||
code: ErrorCode(-32600),
|
||||
message: Cow::Borrowed("Invalid Request"),
|
||||
|
|
|
|||
Loading…
Reference in a new issue