syncable_ag_ui_client/
error.rs1use thiserror::Error;
4
5#[derive(Debug, Error)]
7pub enum ClientError {
8 #[error("connection failed: {0}")]
10 Connection(String),
11
12 #[error("HTTP error: {0}")]
14 Http(#[from] reqwest::Error),
15
16 #[error("WebSocket error: {0}")]
18 WebSocket(#[from] tokio_tungstenite::tungstenite::Error),
19
20 #[error("parse error: {0}")]
22 Parse(String),
23
24 #[error("JSON error: {0}")]
26 Json(#[from] serde_json::Error),
27
28 #[error("SSE error: {0}")]
30 Sse(String),
31
32 #[error("connection closed")]
34 Closed,
35
36 #[error("invalid URL: {0}")]
38 InvalidUrl(String),
39
40 #[error("state error: {0}")]
42 State(String),
43}
44
45impl ClientError {
46 pub fn connection(msg: impl Into<String>) -> Self {
48 Self::Connection(msg.into())
49 }
50
51 pub fn parse(msg: impl Into<String>) -> Self {
53 Self::Parse(msg.into())
54 }
55
56 pub fn sse(msg: impl Into<String>) -> Self {
58 Self::Sse(msg.into())
59 }
60
61 pub fn state(msg: impl Into<String>) -> Self {
63 Self::State(msg.into())
64 }
65}
66
67pub type Result<T> = std::result::Result<T, ClientError>;
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73
74 #[test]
75 fn test_error_display() {
76 let err = ClientError::connection("refused");
77 assert_eq!(format!("{}", err), "connection failed: refused");
78
79 let err = ClientError::parse("invalid JSON");
80 assert_eq!(format!("{}", err), "parse error: invalid JSON");
81
82 let err = ClientError::Closed;
83 assert_eq!(format!("{}", err), "connection closed");
84 }
85
86 #[test]
87 fn test_error_constructors() {
88 let err = ClientError::connection("test");
89 assert!(matches!(err, ClientError::Connection(_)));
90
91 let err = ClientError::sse("stream ended");
92 assert!(matches!(err, ClientError::Sse(_)));
93
94 let err = ClientError::state("invalid patch");
95 assert!(matches!(err, ClientError::State(_)));
96 }
97}