1#[derive(Debug, thiserror::Error)]
5pub enum ChatError {
6 #[error("adapter error: {0}")]
8 Adapter(String),
9
10 #[error("feature not supported: {0}")]
12 NotSupported(String),
13
14 #[error("message not found: {0}")]
16 MessageNotFound(String),
17
18 #[error("send failed: {0}")]
20 SendFailed(String),
21
22 #[error("modal error: {0}")]
24 Modal(String),
25
26 #[error("channel closed")]
28 Closed,
29
30 #[error(transparent)]
32 Internal(#[from] Box<dyn std::error::Error + Send + Sync>),
33}
34
35#[cfg(test)]
36mod tests {
37 use std::fmt::Write;
38
39 use super::*;
40
41 #[test]
42 fn display_adapter() {
43 let err = ChatError::Adapter("timeout".into());
44 assert_eq!(err.to_string(), "adapter error: timeout");
45 }
46
47 #[test]
48 fn display_not_supported() {
49 let err = ChatError::NotSupported("reactions".into());
50 assert_eq!(err.to_string(), "feature not supported: reactions");
51 }
52
53 #[test]
54 fn display_message_not_found() {
55 let err = ChatError::MessageNotFound("msg-42".into());
56 assert_eq!(err.to_string(), "message not found: msg-42");
57 }
58
59 #[test]
60 fn display_send_failed() {
61 let err = ChatError::SendFailed("queue full".into());
62 assert_eq!(err.to_string(), "send failed: queue full");
63 }
64
65 #[test]
66 fn display_modal() {
67 let err = ChatError::Modal("missing field".into());
68 assert_eq!(err.to_string(), "modal error: missing field");
69 }
70
71 #[test]
72 fn display_closed() {
73 let err = ChatError::Closed;
74 assert_eq!(err.to_string(), "channel closed");
75 }
76
77 #[test]
78 fn display_internal_transparent() {
79 let inner: Box<dyn std::error::Error + Send + Sync> = "boom".into();
80 let err = ChatError::Internal(inner);
81 assert_eq!(err.to_string(), "boom");
82 }
83
84 #[test]
85 fn from_boxed_error() {
86 let inner: Box<dyn std::error::Error + Send + Sync> = "something broke".into();
87 let err: ChatError = inner.into();
88 let mut buf = String::new();
89 write!(buf, "{err}").expect("write failed");
90 assert_eq!(buf, "something broke");
91 }
92}