Skip to content

v0.9.0-rc.23

Choose a tag to compare

@github-actions github-actions released this 26 May 04:03
· 71 commits to main since this release
0e3b63c

parse_close_reason structured-variant refactor — closes peat-mesh#164. Replaces substring-on-Display matching in transport::iroh_mesh::IrohMeshConnection::parse_close_reason with an exhaustive structured match on iroh::endpoint::ConnectionError's 8 variants. No transport semantics, peer discovery, or wire-shape change. Documents the stable per-variant payload-tag contract on DisconnectReason::NetworkError / DisconnectReason::ApplicationError's public enum surface in src/transport/mod.rs.

Changed — parse_close_reason structured-variant match (peat-mesh#164)

  • transport::iroh_mesh::IrohMeshConnection::parse_close_reason now pattern-matches on iroh::endpoint::ConnectionError variants directly instead of substring-matching the Display text. Routing key moves from "does the formatted string contain 'timeout'/'reset'/'closed'/'application'?" to "which structured enum variant?". Three regression classes the legacy substring code was vulnerable to are now closed:
    • thiserror wording tweaks in upstream iroh / noq-proto would have silently shifted every disconnect into the NetworkError(_) fallback arm. Structured match is wording-independent.
    • LocallyClosedRemoteClosed confusion — the legacy code's contains("closed") collapsed both into RemoteClosed. The new match disambiguates: LocallyClosedDisconnectReason::LocalClosed, Reset and ConnectionClosed(_)DisconnectReason::RemoteClosed.
    • New iroh variant addition — the exhaustive match in map_connection_error refuses to compile if a ConnectionError variant is added upstream, surfacing the change at peat-mesh CI rather than after a downstream binary swallows it as NetworkError. noq-proto's ConnectionError is not marked #[non_exhaustive] as of 1.0.0-rc.0, so exhaustive match is structurally enforceable.
  • VersionMismatch and CidsExhausted now carry stable per-variant tags ("version-mismatch", "cids-exhausted") in the NetworkError payload instead of the raw Display text. Audit-log parsers downstream stay stable across iroh wording changes.
  • ApplicationClosed(_) payload format: "code={error_code} reason={utf8-lossy(reason)}" — gives operators a structured handle on the close-frame contents instead of an opaque Display.
  • New unit test transport::iroh_mesh::tests::parse_close_reason_per_variant_pin covers the 5 unit-shape variants. The 3 data-bearing variants (ConnectionClosed, ApplicationClosed, TransportError) can't be constructed from outside noq-proto (private/non-exhaustive struct internals), but the exhaustive match in map_connection_error itself is the load-bearing regression guard for new variants.
  • Carryover from peat-protocol's pre-Phase-2 IrohMeshTransport; reviewer of peat-mesh#162 flagged this as a follow-up at the time and explicitly framed it as out-of-scope for that PR (CHANGELOG entry under 0.9.0-rc.21 / 0.9.0-rc.22 "Deferred (tracked separately)").

⚠ Consumer-visible behavior delta

Code that branches on DisconnectReason::RemoteClosed now sees fewer hits and DisconnectReason::LocalClosed sees more, because the legacy contains("closed") substring match collapsed iroh::endpoint::ConnectionError::LocallyClosed into RemoteClosed. Consumers that need to distinguish "we hung up" from "they hung up" — operational dashboards, reconnect-policy gates that suppress on local intentional close — should match LocalClosed separately now; consumers that previously branched only on RemoteClosed will see those locally-initiated closes route to a different arm. Same enum surface, different routing.

Stable payload tags on DisconnectReason::NetworkError and DisconnectReason::ApplicationError are now documented on the enum itself in src/transport/mod.rs — the per-variant tag contract ("version-mismatch", "cids-exhausted", "transport-error: {inner}", "code={n} reason={utf8-lossy(bytes)}") is part of the public surface, not an implementation detail of iroh_mesh. A format_application_close_payload_pin test pins the ApplicationError format directly via an extracted format_application_close(error_code, reason) helper.