Skip to main content

post_cortex_mcp/
error.rs

1// Copyright (c) 2025, 2026 Julius ML
2// Licensed under the MIT License. See LICENSE at the workspace root.
3
4//! Typed error hierarchy for `post-cortex-mcp`.
5//!
6//! Wraps lower-layer errors and adds MCP-specific variants
7//! (validation, JSON-RPC formatting). The [`Error::mcp_code`] method
8//! maps each variant to a JSON-RPC error code transport adapters can
9//! use directly.
10
11use thiserror::Error;
12
13/// Errors produced by the MCP tool layer.
14#[derive(Debug, Error)]
15pub enum Error {
16    /// Caller's MCP tool params failed validation.
17    #[error("validation error: {0}")]
18    Validation(String),
19
20    /// Underlying memory / orchestrator error.
21    #[error(transparent)]
22    Memory(#[from] post_cortex_memory::error::Error),
23
24    /// Underlying storage error (exposed when the MCP tool calls into
25    /// storage directly, e.g. session list).
26    #[error(transparent)]
27    Storage(#[from] post_cortex_storage::error::Error),
28
29    /// JSON (de)serialization failed at the MCP boundary.
30    #[error("json error: {0}")]
31    Json(#[from] serde_json::Error),
32
33    /// Catch-all for migrating call sites that still use `anyhow`.
34    #[error(transparent)]
35    External(#[from] anyhow::Error),
36}
37
38/// Crate-level result alias.
39pub type Result<T, E = Error> = std::result::Result<T, E>;
40
41impl Error {
42    /// A stable discriminant for metrics / structured logs.
43    #[must_use]
44    pub fn kind(&self) -> &'static str {
45        match self {
46            Self::Validation(_) => "validation",
47            Self::Memory(_) => "memory",
48            Self::Storage(_) => "storage",
49            Self::Json(_) => "json",
50            Self::External(_) => "external",
51        }
52    }
53
54    /// Map to a JSON-RPC error code per the MCP spec.
55    ///
56    /// - `-32602` Invalid params (validation failures).
57    /// - `-32603` Internal error (everything else).
58    #[must_use]
59    pub fn mcp_code(&self) -> i32 {
60        match self {
61            Self::Validation(_) => -32602,
62            _ => -32603,
63        }
64    }
65}