1use thiserror::Error;
2
3pub const PARSE_ERROR: i32 = -32700;
5pub const INVALID_REQUEST: i32 = -32600;
6pub const METHOD_NOT_FOUND: i32 = -32601;
7pub const INVALID_PARAMS: i32 = -32602;
8pub const INTERNAL_ERROR: i32 = -32603;
9
10pub const TASK_NOT_FOUND: i32 = -32001;
12pub const TASK_NOT_CANCELABLE: i32 = -32002;
13pub const PUSH_NOTIFICATION_NOT_SUPPORTED: i32 = -32003;
14pub const UNSUPPORTED_OPERATION: i32 = -32004;
15pub const CONTENT_TYPE_NOT_SUPPORTED: i32 = -32005;
16pub const INVALID_AGENT_RESPONSE: i32 = -32006;
17pub const AUTHENTICATED_EXTENDED_CARD_NOT_CONFIGURED: i32 = -32007;
18
19pub const DATABASE_ERROR: i32 = -32100;
21
22#[derive(Error, Debug)]
24pub enum A2AError {
25 #[error("JSON-RPC error: {code} - {message}")]
26 JsonRpc {
27 code: i32,
28 message: String,
29 data: Option<serde_json::Value>,
30 },
31
32 #[error("JSON parse error: {0}")]
33 JsonParse(#[from] serde_json::Error),
34
35 #[error("Invalid request: {0}")]
36 InvalidRequest(String),
37
38 #[error("Invalid parameters: {0}")]
39 InvalidParams(String),
40
41 #[error("Method not found: {0}")]
42 MethodNotFound(String),
43
44 #[error("Task not found: {0}")]
45 TaskNotFound(String),
46
47 #[error("Task not cancelable: {0}")]
48 TaskNotCancelable(String),
49
50 #[error("Push notification not supported")]
51 PushNotificationNotSupported,
52
53 #[error("Unsupported operation: {0}")]
54 UnsupportedOperation(String),
55
56 #[error("Content type not supported: {0}")]
57 ContentTypeNotSupported(String),
58
59 #[error("Invalid agent response: {0}")]
60 InvalidAgentResponse(String),
61
62 #[error("Authenticated extended card not configured")]
63 AuthenticatedExtendedCardNotConfigured,
64
65 #[error("Internal error: {0}")]
66 Internal(String),
67
68 #[error("Validation error in {field}: {message}")]
69 ValidationError { field: String, message: String },
70
71 #[error("Database error: {0}")]
72 DatabaseError(String),
73
74 #[error("IO error: {0}")]
75 Io(#[from] std::io::Error),
76}
77
78impl A2AError {
79 pub fn to_jsonrpc_error(&self) -> serde_json::Value {
81 let (code, message) = match self {
82 A2AError::JsonParse(_) => (PARSE_ERROR, "Invalid JSON payload"),
83 A2AError::InvalidRequest(_) => (INVALID_REQUEST, "Request payload validation error"),
84 A2AError::MethodNotFound(_) => (METHOD_NOT_FOUND, "Method not found"),
85 A2AError::InvalidParams(_) => (INVALID_PARAMS, "Invalid parameters"),
86 A2AError::TaskNotFound(_) => (TASK_NOT_FOUND, "Task not found"),
87 A2AError::TaskNotCancelable(_) => (TASK_NOT_CANCELABLE, "Task cannot be canceled"),
88 A2AError::PushNotificationNotSupported => (
89 PUSH_NOTIFICATION_NOT_SUPPORTED,
90 "Push Notification is not supported",
91 ),
92 A2AError::UnsupportedOperation(_) => {
93 (UNSUPPORTED_OPERATION, "This operation is not supported")
94 }
95 A2AError::ContentTypeNotSupported(_) => {
96 (CONTENT_TYPE_NOT_SUPPORTED, "Incompatible content types")
97 }
98 A2AError::InvalidAgentResponse(_) => (INVALID_AGENT_RESPONSE, "Invalid agent response"),
99 A2AError::AuthenticatedExtendedCardNotConfigured => (
100 AUTHENTICATED_EXTENDED_CARD_NOT_CONFIGURED,
101 "Authenticated Extended Card is not configured",
102 ),
103 A2AError::ValidationError { .. } => (INVALID_PARAMS, "Validation error"),
104 A2AError::DatabaseError(_) => (DATABASE_ERROR, "Database error"),
105 A2AError::Internal(_) => (INTERNAL_ERROR, "Internal error"),
106 _ => (INTERNAL_ERROR, "Internal error"),
107 };
108
109 serde_json::json!({
110 "code": code,
111 "message": message,
112 "data": null,
113 })
114 }
115}