swarm repositories / source
aboutsummaryrefslogtreecommitdiff
path: root/crates/fidget-spinner-cli/src/mcp/fault.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/fidget-spinner-cli/src/mcp/fault.rs')
-rw-r--r--crates/fidget-spinner-cli/src/mcp/fault.rs99
1 files changed, 99 insertions, 0 deletions
diff --git a/crates/fidget-spinner-cli/src/mcp/fault.rs b/crates/fidget-spinner-cli/src/mcp/fault.rs
new file mode 100644
index 0000000..e9d1fce
--- /dev/null
+++ b/crates/fidget-spinner-cli/src/mcp/fault.rs
@@ -0,0 +1,99 @@
+use serde::{Deserialize, Serialize};
+use serde_json::{Value, json};
+use time::OffsetDateTime;
+
+#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
+pub(crate) enum FaultKind {
+ InvalidInput,
+ NotInitialized,
+ Unavailable,
+ Transient,
+ Internal,
+}
+
+#[derive(Clone, Copy, Debug, Deserialize, Eq, PartialEq, Serialize)]
+pub(crate) enum FaultStage {
+ Host,
+ Worker,
+ Store,
+ Transport,
+ Protocol,
+ Rollout,
+}
+
+#[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)]
+pub(crate) struct FaultRecord {
+ pub kind: FaultKind,
+ pub stage: FaultStage,
+ pub operation: String,
+ pub message: String,
+ pub retryable: bool,
+ pub retried: bool,
+ pub worker_generation: Option<u64>,
+ pub occurred_at: OffsetDateTime,
+}
+
+impl FaultRecord {
+ #[must_use]
+ pub fn new(
+ kind: FaultKind,
+ stage: FaultStage,
+ operation: impl Into<String>,
+ message: impl Into<String>,
+ ) -> Self {
+ Self {
+ kind,
+ stage,
+ operation: operation.into(),
+ message: message.into(),
+ retryable: false,
+ retried: false,
+ worker_generation: None,
+ occurred_at: OffsetDateTime::now_utc(),
+ }
+ }
+
+ #[must_use]
+ pub fn retryable(mut self, worker_generation: Option<u64>) -> Self {
+ self.retryable = true;
+ self.worker_generation = worker_generation;
+ self
+ }
+
+ #[must_use]
+ pub fn mark_retried(mut self) -> Self {
+ self.retried = true;
+ self
+ }
+
+ #[must_use]
+ pub fn into_jsonrpc_error(self) -> Value {
+ json!({
+ "code": self.jsonrpc_code(),
+ "message": self.message.clone(),
+ "data": self,
+ })
+ }
+
+ #[must_use]
+ pub fn into_tool_result(self) -> Value {
+ json!({
+ "content": [{
+ "type": "text",
+ "text": self.message,
+ }],
+ "structuredContent": self,
+ "isError": true,
+ })
+ }
+
+ #[must_use]
+ pub const fn jsonrpc_code(&self) -> i64 {
+ match self.kind {
+ FaultKind::InvalidInput => -32602,
+ FaultKind::NotInitialized => -32002,
+ FaultKind::Unavailable => -32004,
+ FaultKind::Transient | FaultKind::Internal => -32603,
+ }
+ }
+}