diff options
| author | main <main@swarm.moe> | 2026-03-19 15:49:41 -0400 |
|---|---|---|
| committer | main <main@swarm.moe> | 2026-03-19 15:49:41 -0400 |
| commit | fa1bd32800b65aab31ea732dd240261b4047522c (patch) | |
| tree | 2fd08af6f36b8beb3c7c941990becc1a0a091d62 /crates/ra-mcp-domain/src/fault.rs | |
| download | adequate-rust-mcp-1.0.0.zip | |
Release adequate-rust-mcp 1.0.0v1.0.0
Diffstat (limited to 'crates/ra-mcp-domain/src/fault.rs')
| -rw-r--r-- | crates/ra-mcp-domain/src/fault.rs | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/crates/ra-mcp-domain/src/fault.rs b/crates/ra-mcp-domain/src/fault.rs new file mode 100644 index 0000000..6d404ab --- /dev/null +++ b/crates/ra-mcp-domain/src/fault.rs @@ -0,0 +1,129 @@ +//! Fault taxonomy and recovery guidance. + +use crate::types::Generation; +use serde::{Deserialize, Serialize}; +use thiserror::Error; + +/// Logical fault class. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum FaultClass { + /// Underlying I/O or transport channel failure. + Transport, + /// Child process startup/liveness/exiting failures. + Process, + /// Malformed or unexpected protocol payloads. + Protocol, + /// Deadline exceeded. + Timeout, + /// Internal resource budget exhaustion. + Resource, +} + +/// Fine-grained fault code. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum FaultCode { + /// Pipe write failed with `EPIPE`. + BrokenPipe, + /// Pipe reached EOF. + UnexpectedEof, + /// Child process exited unexpectedly. + ChildExited, + /// Child process failed to spawn. + SpawnFailed, + /// Startup sequence exceeded deadline. + StartupTimedOut, + /// Request exceeded deadline. + RequestTimedOut, + /// Received an invalid protocol frame. + InvalidFrame, + /// Received invalid JSON. + InvalidJson, + /// Response could not be correlated with a pending request. + UnknownResponseId, +} + +/// Recovery strategy for a fault. +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +pub enum RecoveryDirective { + /// Retry the request on the same process. + RetryInPlace, + /// Restart the worker process and retry once. + RestartAndReplay, + /// Fail-fast and bubble to the caller. + AbortRequest, +} + +/// Structured fault event. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct Fault { + /// Generation in which this fault happened. + pub generation: Generation, + /// Broad fault class. + pub class: FaultClass, + /// Specific fault code. + pub code: FaultCode, + /// Caller-facing context. + pub detail: FaultDetail, +} + +impl Fault { + /// Constructs a new fault. + #[must_use] + pub fn new( + generation: Generation, + class: FaultClass, + code: FaultCode, + detail: FaultDetail, + ) -> Self { + Self { + generation, + class, + code, + detail, + } + } + + /// Returns the default recovery directive for this fault. + #[must_use] + pub fn directive(&self) -> RecoveryDirective { + match (self.class, self.code) { + (FaultClass::Transport, FaultCode::BrokenPipe) + | (FaultClass::Transport, FaultCode::UnexpectedEof) + | (FaultClass::Process, FaultCode::ChildExited) + | (FaultClass::Process, FaultCode::SpawnFailed) + | (FaultClass::Timeout, FaultCode::StartupTimedOut) => { + RecoveryDirective::RestartAndReplay + } + (FaultClass::Timeout, FaultCode::RequestTimedOut) => { + RecoveryDirective::RestartAndReplay + } + (FaultClass::Protocol, FaultCode::UnknownResponseId) => RecoveryDirective::RetryInPlace, + (FaultClass::Protocol, FaultCode::InvalidFrame) + | (FaultClass::Protocol, FaultCode::InvalidJson) + | (FaultClass::Resource, _) => RecoveryDirective::AbortRequest, + _ => RecoveryDirective::AbortRequest, + } + } +} + +/// Typed detail payload for a fault. +#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct FaultDetail { + /// Human-consumable context. + pub message: String, +} + +impl FaultDetail { + /// Creates a new detail message. + #[must_use] + pub fn new(message: impl Into<String>) -> Self { + Self { + message: message.into(), + } + } +} + +/// Domain fault conversion error. +#[derive(Debug, Error)] +#[error("fault conversion failure: {0}")] +pub struct FaultConversionError(String); |