#![allow(dead_code)]
use rmcp::ErrorData as McpError;
use thiserror::Error;
#[derive(Debug, Error)]
pub enum MonarchError {
#[error("Monarch session expired — please re-run `monarch-mcp login` to re-authenticate")]
SessionExpired,
#[error("Goals file error: {0}")]
GoalsFile(String),
#[error("Monarch GraphQL error: {0}")]
GraphQL(String),
#[error("HTTP error: {0}")]
Http(#[from] reqwest::Error),
#[error("Internal error: {0}")]
Internal(String),
}
impl MonarchError {
pub fn into_mcp_error(self) -> McpError {
McpError::internal_error(self.to_string(), None)
}
pub fn is_auth_error(&self) -> bool {
matches!(self, MonarchError::SessionExpired)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn session_expired_message_contains_reauth_hint() {
let err = MonarchError::SessionExpired;
let msg = err.to_string();
assert!(
msg.contains("re-authenticate") || msg.contains("login"),
"expected re-auth hint in: {msg}"
);
}
#[test]
fn session_expired_is_detected_as_auth_error() {
assert!(MonarchError::SessionExpired.is_auth_error());
}
#[test]
fn other_errors_are_not_auth_errors() {
assert!(!MonarchError::Internal("boom".into()).is_auth_error());
assert!(!MonarchError::GraphQL("bad query".into()).is_auth_error());
}
#[test]
fn into_mcp_error_preserves_message() {
let err = MonarchError::SessionExpired;
let msg = err.to_string();
let mcp = MonarchError::SessionExpired.into_mcp_error();
assert!(mcp.message.contains("re-authenticate") || mcp.message.contains(&msg[..20]));
}
}