use std::fmt;
#[derive(Debug)]
pub enum CompositionError {
ServerNotFound(String),
ConnectionFailed(String),
ToolCallFailed {
server_id: String,
tool_name: String,
message: String,
},
ResourceReadFailed {
server_id: String,
uri: String,
message: String,
},
PromptFailed {
server_id: String,
prompt_name: String,
message: String,
},
Deserialization(String),
Serialization(String),
InvalidResponse(String),
Configuration(String),
Transport(String),
ServerError {
code: i32,
message: String,
},
Timeout(String),
Unavailable(String),
}
impl fmt::Display for CompositionError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::ServerNotFound(id) => {
write!(f, "Foundation server not found: {}", id)
},
Self::ConnectionFailed(msg) => {
write!(f, "Failed to connect to foundation server: {}", msg)
},
Self::ToolCallFailed {
server_id,
tool_name,
message,
} => {
write!(
f,
"Tool call failed on {}/{}: {}",
server_id, tool_name, message
)
},
Self::ResourceReadFailed {
server_id,
uri,
message,
} => {
write!(
f,
"Resource read failed on {}/{}: {}",
server_id, uri, message
)
},
Self::PromptFailed {
server_id,
prompt_name,
message,
} => {
write!(
f,
"Prompt failed on {}/{}: {}",
server_id, prompt_name, message
)
},
Self::Deserialization(msg) => {
write!(f, "Deserialization error: {}", msg)
},
Self::Serialization(msg) => {
write!(f, "Serialization error: {}", msg)
},
Self::InvalidResponse(msg) => {
write!(f, "Invalid response: {}", msg)
},
Self::Configuration(msg) => {
write!(f, "Configuration error: {}", msg)
},
Self::Transport(msg) => {
write!(f, "Transport error: {}", msg)
},
Self::ServerError { code, message } => {
write!(f, "Server error ({}): {}", code, message)
},
Self::Timeout(msg) => {
write!(f, "Operation timed out: {}", msg)
},
Self::Unavailable(msg) => {
write!(f, "Server unavailable: {}", msg)
},
}
}
}
impl std::error::Error for CompositionError {}
impl From<serde_json::Error> for CompositionError {
fn from(err: serde_json::Error) -> Self {
Self::Deserialization(err.to_string())
}
}
impl From<std::io::Error> for CompositionError {
fn from(err: std::io::Error) -> Self {
Self::Configuration(err.to_string())
}
}
impl From<toml::de::Error> for CompositionError {
fn from(err: toml::de::Error) -> Self {
Self::Configuration(format!("TOML parse error: {}", err))
}
}
impl From<crate::Error> for CompositionError {
fn from(err: crate::Error) -> Self {
Self::Transport(err.to_string())
}
}
impl From<CompositionError> for crate::Error {
fn from(err: CompositionError) -> Self {
Self::internal(err.to_string())
}
}