dstar_gateway_core/error/
timeout.rs1use std::net::SocketAddr;
4use std::time::Duration;
5
6use crate::types::StreamId;
7
8#[derive(Debug, Clone, thiserror::Error)]
13#[non_exhaustive]
14pub enum TimeoutError {
15 #[error("connect timeout: deadline {deadline:?}, elapsed {elapsed:?}, last state {last_state}")]
17 Connect {
18 deadline: Duration,
20 elapsed: Duration,
22 last_state: &'static str,
25 },
26
27 #[error("keepalive inactivity: deadline {deadline:?}, elapsed {elapsed:?}, peer {peer}")]
29 KeepaliveInactivity {
30 deadline: Duration,
32 elapsed: Duration,
34 peer: SocketAddr,
36 },
37
38 #[error("disconnect ack timeout: deadline {deadline:?}, elapsed {elapsed:?}")]
40 Disconnect {
41 deadline: Duration,
43 elapsed: Duration,
45 },
46
47 #[error("voice inactivity on stream {stream_id}, elapsed {elapsed:?}")]
49 VoiceInactivity {
50 stream_id: StreamId,
52 elapsed: Duration,
54 },
55
56 #[error("auth connect timeout: deadline {deadline:?}, elapsed {elapsed:?}")]
58 AuthConnect {
59 deadline: Duration,
61 elapsed: Duration,
63 },
64
65 #[error(
67 "auth read stalled: deadline {deadline:?}, elapsed {elapsed:?}, {bytes_so_far} bytes received"
68 )]
69 AuthRead {
70 deadline: Duration,
72 elapsed: Duration,
74 bytes_so_far: usize,
76 },
77}
78
79#[cfg(test)]
80mod tests {
81 use std::net::{IpAddr, Ipv4Addr};
82
83 use super::*;
84
85 const CAFE: StreamId = {
86 StreamId::new(0xCAFE).unwrap()
89 };
90
91 #[test]
92 fn timeout_connect_display_includes_state() {
93 let err = TimeoutError::Connect {
94 deadline: Duration::from_secs(5),
95 elapsed: Duration::from_secs(5),
96 last_state: "Connecting",
97 };
98 let s = err.to_string();
99 assert!(s.contains("Connecting"));
100 }
101
102 #[test]
103 fn timeout_keepalive_includes_peer() {
104 let peer = SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 20001);
105 let err = TimeoutError::KeepaliveInactivity {
106 deadline: Duration::from_secs(30),
107 elapsed: Duration::from_secs(31),
108 peer,
109 };
110 let s = err.to_string();
111 assert!(s.contains("127.0.0.1:20001"));
112 }
113
114 #[test]
115 fn timeout_voice_inactivity_includes_stream_id() {
116 let err = TimeoutError::VoiceInactivity {
117 stream_id: CAFE,
118 elapsed: Duration::from_secs(2),
119 };
120 let s = err.to_string();
121 assert!(s.contains("0xCAFE"));
122 }
123}