Skip to main content

a2a_client/
error.rs

1//! Error types for the a2a-client library.
2
3use thiserror::Error;
4
5/// Errors that can occur when using the A2A client.
6#[derive(Error, Debug)]
7pub enum ClientError {
8    /// Error from the underlying A2A protocol client
9    #[error("A2A protocol error: {0}")]
10    A2AError(#[from] a2a_rs::A2AError),
11
12    /// WebSocket is not configured
13    #[error(
14        "WebSocket client not configured. Actionable Suggestion: Ensure that a WebSocket interface is defined in preferred_transport or additional_interfaces on the agent card, or manually configure a WebSocket URL using WebA2AClientBuilder::ws_url."
15    )]
16    WebSocketNotConfigured,
17
18    /// Transport auto-detection failed
19    #[error(
20        "Failed to auto-detect available transports: {0}. Actionable Suggestion: Make sure the agent server is running, the host is reachable, and the `/agent-card` endpoint is accessible."
21    )]
22    AutoDetectionFailed(String),
23
24    /// Invalid configuration
25    #[error(
26        "Invalid configuration: {0}. Actionable Suggestion: Verify that builder configuration parameters, such as base URLs, are correctly specified."
27    )]
28    InvalidConfiguration(String),
29
30    /// URL parsing/formatting failure
31    #[error(
32        "Invalid URL format: '{url}'. Reason: {reason}. Actionable Suggestion: Double check that the URL scheme and address are valid and formatted correctly."
33    )]
34    InvalidUrl { url: String, reason: String },
35
36    /// Serialization/deserialization error
37    #[error(
38        "Data serialization error: {0}. Actionable Suggestion: Check that payloads adhere to the expected format and structure."
39    )]
40    SerializationError(String),
41}
42
43/// Specialized Result type for client operations
44pub type Result<T> = std::result::Result<T, ClientError>;
45
46#[cfg(test)]
47mod tests {
48    use super::*;
49
50    #[test]
51    fn test_client_error_formatting() {
52        let err = ClientError::WebSocketNotConfigured;
53        let msg = err.to_string();
54        assert!(msg.contains("WebSocket client not configured."));
55        assert!(msg.contains("Actionable Suggestion:"));
56
57        let err = ClientError::AutoDetectionFailed("No matching transport".to_string());
58        let msg = err.to_string();
59        assert!(msg.contains("No matching transport"));
60        assert!(msg.contains("Failed to auto-detect"));
61        assert!(msg.contains("Actionable Suggestion:"));
62
63        let err = ClientError::InvalidConfiguration("Missing field".to_string());
64        let msg = err.to_string();
65        assert!(msg.contains("Missing field"));
66        assert!(msg.contains("Actionable Suggestion:"));
67
68        let err = ClientError::InvalidUrl {
69            url: "http://invalid".to_string(),
70            reason: "Bad format".to_string(),
71        };
72        let msg = err.to_string();
73        assert!(msg.contains("http://invalid"));
74        assert!(msg.contains("Bad format"));
75        assert!(msg.contains("Actionable Suggestion:"));
76
77        let err = ClientError::SerializationError("JSON error".to_string());
78        let msg = err.to_string();
79        assert!(msg.contains("JSON error"));
80        assert!(msg.contains("Actionable Suggestion:"));
81    }
82}