serdes_ai_streaming/
error.rs1use thiserror::Error;
4
5#[derive(Debug, Error)]
7pub enum StreamError {
8 #[error("Model error: {0}")]
10 Model(String),
11
12 #[error("Failed to parse delta: {0}")]
14 ParseDelta(String),
15
16 #[error("Failed to parse SSE event: {0}")]
18 ParseSse(String),
19
20 #[error("JSON error: {0}")]
22 Json(#[from] serde_json::Error),
23
24 #[error("IO error: {0}")]
26 Io(#[from] std::io::Error),
27
28 #[error("Stream interrupted")]
30 Interrupted,
31
32 #[error("Timeout waiting for delta")]
34 Timeout,
35
36 #[error("Connection closed unexpectedly")]
38 ConnectionClosed,
39
40 #[error("Connection error: {0}")]
42 Connection(String),
43
44 #[error("Send error: {0}")]
46 Send(String),
47
48 #[error("Receive error: {0}")]
50 Receive(String),
51
52 #[error("Serialization error: {0}")]
54 Serialization(String),
55
56 #[error("Invalid state: {0}")]
58 InvalidState(String),
59
60 #[error("SSE buffer exceeded maximum size")]
62 BufferOverflow,
63
64 #[error("{0}")]
66 Other(String),
67}
68
69impl StreamError {
70 #[must_use]
72 pub fn is_recoverable(&self) -> bool {
73 matches!(self, Self::Timeout | Self::Interrupted)
74 }
75
76 pub fn from_err<E: std::fmt::Display>(err: E) -> Self {
78 Self::Other(err.to_string())
79 }
80}
81
82pub type StreamResult<T> = Result<T, StreamError>;
84
85#[cfg(test)]
86mod tests {
87 use super::*;
88
89 #[test]
90 fn test_error_display() {
91 let err = StreamError::Timeout;
92 assert_eq!(err.to_string(), "Timeout waiting for delta");
93 }
94
95 #[test]
96 fn test_recoverable() {
97 assert!(StreamError::Timeout.is_recoverable());
98 assert!(StreamError::Interrupted.is_recoverable());
99 assert!(!StreamError::ConnectionClosed.is_recoverable());
100 }
101}