Skip to main content

contextvm_sdk/transport/open_stream/
errors.rs

1//! Error taxonomy for CEP-41 open streams.
2//!
3//! Mirrors the TypeScript SDK's error classes
4//! (`sdk/src/transport/open-stream/errors.ts`) so failure classification is
5//! identical across implementations. Surfaced through the crate-level
6//! [`crate::Error`] via a `#[from]` conversion.
7
8/// Errors raised while reading, writing, or sequencing an open stream.
9#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
10pub enum OpenStreamError {
11    /// The stream was aborted locally or by the remote peer (terminal).
12    #[error("Open stream aborted (token: {token}){}", .reason.as_deref().map(|r| format!(": {r}")).unwrap_or_default())]
13    Abort {
14        /// The `progressToken` of the aborted stream.
15        token: String,
16        /// Optional advisory reason supplied in the `abort` frame.
17        reason: Option<String>,
18    },
19
20    /// A stream violated local admission or buffering policy
21    /// (concurrency, buffered-chunk count, buffered+queued byte budget).
22    #[error("Open stream policy violation: {0}")]
23    Policy(String),
24
25    /// Frames violated CEP-41 lifecycle or ordering rules (non-increasing
26    /// progress, stale/duplicate `chunkIndex`, frame before `start`, frame
27    /// after a terminal close/abort, incomplete `close.lastChunkIndex`).
28    #[error("Open stream sequence error: {0}")]
29    Sequence(String),
30}
31
32impl OpenStreamError {
33    /// Construct an [`OpenStreamError::Abort`].
34    pub fn abort(token: impl Into<String>, reason: Option<String>) -> Self {
35        Self::Abort {
36            token: token.into(),
37            reason,
38        }
39    }
40
41    /// Returns `true` if this is a terminal [`abort`](OpenStreamError::Abort).
42    pub fn is_abort(&self) -> bool {
43        matches!(self, Self::Abort { .. })
44    }
45}
46
47// The crate-level `From<OpenStreamError> for crate::Error` conversion is
48// generated by the `#[from]` attribute on `Error::OpenStream` (see
49// `src/core/error.rs`), mirroring `OversizedTransferError`.