use rs_genai::session::SessionError;
#[derive(Debug, thiserror::Error)]
pub enum AgentError {
#[error("Session error: {0}")]
Session(#[from] SessionError),
#[error("Tool error: {0}")]
Tool(#[from] ToolError),
#[error("Unknown agent: {0}")]
UnknownAgent(String),
#[error("Transfer requested to agent: {0}")]
TransferRequested(String),
#[error("Agent transfer failed: {0}")]
TransferFailed(String),
#[error("Agent session closed")]
SessionClosed,
#[error("Timeout")]
Timeout,
#[error("Configuration error: {0}")]
Config(String),
#[error("{0}")]
Other(String),
}
#[derive(Debug, Clone, thiserror::Error)]
pub enum ToolError {
#[error("Tool execution failed: {0}")]
ExecutionFailed(String),
#[error("Tool not found: {0}")]
NotFound(String),
#[error("Invalid arguments: {0}")]
InvalidArgs(String),
#[error("Tool cancelled")]
Cancelled,
#[error("Tool execution timed out after {0:?}")]
Timeout(std::time::Duration),
#[error("{0}")]
Other(String),
}
#[cfg(test)]
mod tests {
use super::*;
use std::time::Duration;
#[test]
fn agent_error_display_messages() {
let err = AgentError::UnknownAgent("foo".into());
assert_eq!(err.to_string(), "Unknown agent: foo");
let err = AgentError::TransferRequested("bar".into());
assert_eq!(err.to_string(), "Transfer requested to agent: bar");
let err = AgentError::TransferFailed("baz".into());
assert_eq!(err.to_string(), "Agent transfer failed: baz");
let err = AgentError::SessionClosed;
assert_eq!(err.to_string(), "Agent session closed");
let err = AgentError::Timeout;
assert_eq!(err.to_string(), "Timeout");
let err = AgentError::Config("bad value".into());
assert_eq!(err.to_string(), "Configuration error: bad value");
let err = AgentError::Other("something".into());
assert_eq!(err.to_string(), "something");
}
#[test]
fn agent_error_from_session_error() {
use rs_genai::session::SessionError;
use rs_genai::session::WebSocketError;
let ws_err = SessionError::WebSocket(WebSocketError::ConnectionRefused("refused".into()));
let agent_err: AgentError = ws_err.into();
let msg = agent_err.to_string();
assert!(msg.contains("Session error"), "got: {msg}");
}
#[test]
fn agent_error_from_tool_error() {
let tool_err = ToolError::NotFound("my_tool".into());
let agent_err: AgentError = tool_err.into();
let msg = agent_err.to_string();
assert!(msg.contains("Tool error"), "got: {msg}");
assert!(msg.contains("my_tool"), "got: {msg}");
}
#[test]
fn tool_error_display_messages() {
assert_eq!(
ToolError::ExecutionFailed("boom".into()).to_string(),
"Tool execution failed: boom"
);
assert_eq!(
ToolError::NotFound("x".into()).to_string(),
"Tool not found: x"
);
assert_eq!(
ToolError::InvalidArgs("bad".into()).to_string(),
"Invalid arguments: bad"
);
assert_eq!(ToolError::Cancelled.to_string(), "Tool cancelled");
assert_eq!(ToolError::Other("misc".into()).to_string(), "misc");
}
#[test]
fn tool_error_timeout_shows_duration() {
let err = ToolError::Timeout(Duration::from_secs(5));
let msg = err.to_string();
assert!(msg.contains("5s"), "got: {msg}");
assert!(msg.contains("timed out"), "got: {msg}");
}
#[test]
fn tool_error_is_clone() {
let err = ToolError::ExecutionFailed("test".into());
let cloned = err.clone();
assert_eq!(err.to_string(), cloned.to_string());
let err2 = ToolError::Timeout(Duration::from_millis(100));
let cloned2 = err2.clone();
assert_eq!(err2.to_string(), cloned2.to_string());
}
}