bamboo_infrastructure/llm/protocol/
errors.rs1use thiserror::Error;
4
5#[derive(Error, Debug)]
6pub enum ProtocolError {
7 #[error("Serialization error: {0}")]
8 Serialization(#[from] serde_json::Error),
9
10 #[error("Invalid role: {0}")]
11 InvalidRole(String),
12
13 #[error("Invalid content format: {0}")]
14 InvalidContent(String),
15
16 #[error("Missing required field: {0}")]
17 MissingField(String),
18
19 #[error("Unsupported feature '{feature}' for protocol '{protocol}'")]
20 UnsupportedFeature { feature: String, protocol: String },
21
22 #[error("Invalid tool call: {0}")]
23 InvalidToolCall(String),
24
25 #[error("Invalid stream chunk: {0}")]
26 InvalidStreamChunk(String),
27
28 #[error("Protocol conversion error: {0}")]
29 Conversion(String),
30}
31
32pub type ProtocolResult<T> = Result<T, ProtocolError>;
33
34#[cfg(test)]
35mod tests {
36 use super::*;
37
38 #[test]
39 fn test_protocol_error_serialization() {
40 let err = ProtocolError::InvalidRole("test".to_string());
41 let msg = err.to_string();
42 assert!(msg.contains("Invalid role"));
43 assert!(msg.contains("test"));
44 }
45
46 #[test]
47 fn test_protocol_error_invalid_content() {
48 let err = ProtocolError::InvalidContent("bad format".to_string());
49 let msg = err.to_string();
50 assert!(msg.contains("Invalid content format"));
51 }
52
53 #[test]
54 fn test_protocol_error_missing_field() {
55 let err = ProtocolError::MissingField("id".to_string());
56 let msg = err.to_string();
57 assert!(msg.contains("Missing required field"));
58 assert!(msg.contains("id"));
59 }
60
61 #[test]
62 fn test_protocol_error_unsupported_feature() {
63 let err = ProtocolError::UnsupportedFeature {
64 feature: "vision".to_string(),
65 protocol: "gemini".to_string(),
66 };
67 let msg = err.to_string();
68 assert!(msg.contains("Unsupported feature"));
69 assert!(msg.contains("vision"));
70 assert!(msg.contains("gemini"));
71 }
72
73 #[test]
74 fn test_protocol_error_invalid_tool_call() {
75 let err = ProtocolError::InvalidToolCall("missing name".to_string());
76 let msg = err.to_string();
77 assert!(msg.contains("Invalid tool call"));
78 }
79
80 #[test]
81 fn test_protocol_error_invalid_stream_chunk() {
82 let err = ProtocolError::InvalidStreamChunk("empty content".to_string());
83 let msg = err.to_string();
84 assert!(msg.contains("Invalid stream chunk"));
85 }
86
87 #[test]
88 fn test_protocol_error_conversion() {
89 let err = ProtocolError::Conversion("failed to convert".to_string());
90 let msg = err.to_string();
91 assert!(msg.contains("Protocol conversion error"));
92 }
93
94 #[test]
95 fn test_protocol_error_debug() {
96 let err = ProtocolError::InvalidRole("test".to_string());
97 let debug_str = format!("{:?}", err);
98 assert!(debug_str.contains("InvalidRole"));
99 }
100
101 #[test]
102 fn test_protocol_result_ok() {
103 let result: ProtocolResult<String> = Ok("success".to_string());
104 assert!(result.is_ok());
105 }
106
107 #[test]
108 fn test_protocol_result_err() {
109 let result: ProtocolResult<String> = Err(ProtocolError::MissingField("test".to_string()));
110 assert!(result.is_err());
111 }
112
113 #[test]
114 fn test_protocol_error_from_serde_json() {
115 let json_err = serde_json::from_str::<i32>("invalid");
116 assert!(json_err.is_err());
117 let protocol_err: ProtocolError = json_err.unwrap_err().into();
118 assert!(matches!(protocol_err, ProtocolError::Serialization(_)));
119 }
120}