Skip to main content

bob_chat/
error.rs

1//! Chat-specific error types.
2
3/// Errors that can occur in the chat channel layer.
4#[derive(Debug, thiserror::Error)]
5pub enum ChatError {
6    /// An adapter-level failure (e.g. transport or protocol mismatch).
7    #[error("adapter error: {0}")]
8    Adapter(String),
9
10    /// The requested feature is not supported by the current adapter.
11    #[error("feature not supported: {0}")]
12    NotSupported(String),
13
14    /// A message with the given identifier was not found.
15    #[error("message not found: {0}")]
16    MessageNotFound(String),
17
18    /// Sending a message failed.
19    #[error("send failed: {0}")]
20    SendFailed(String),
21
22    /// A modal interaction error.
23    #[error("modal error: {0}")]
24    Modal(String),
25
26    /// The underlying channel has been closed.
27    #[error("channel closed")]
28    Closed,
29
30    /// An opaque internal error from a lower layer.
31    #[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}