Skip to main content

altair_server/
error.rs

1//! Crate-wide error type for `altair-server`.
2
3use thiserror::Error;
4
5/// Errors returned by `altair-server` operations.
6#[derive(Debug, Error)]
7#[non_exhaustive]
8pub enum Error {
9    /// Failed to bind the TCP listener.
10    #[error("failed to bind {addr}: {source}")]
11    Bind {
12        /// The address we attempted to bind.
13        addr: String,
14        /// Underlying I/O error.
15        #[source]
16        source: std::io::Error,
17    },
18
19    /// I/O error during the serve loop.
20    #[error("server I/O: {0}")]
21    Io(#[from] std::io::Error),
22
23    /// Builder rejected a configuration value (bad bind address, etc.).
24    #[error("server configuration: {0}")]
25    Configuration(String),
26
27    /// In-flight requests did not drain within the configured
28    /// `shutdown_timeout` after the shutdown future resolved.
29    #[error("graceful shutdown timed out after {0:?}")]
30    ShutdownTimeout(std::time::Duration),
31}
32
33/// Convenience result alias for this crate.
34pub type Result<T> = std::result::Result<T, Error>;
35
36#[cfg(test)]
37mod tests {
38    use super::*;
39
40    #[test]
41    fn bind_error_renders_addr_and_source() {
42        let e = Error::Bind {
43            addr: "0.0.0.0:8080".into(),
44            source: std::io::Error::other("address in use"),
45        };
46        let s = e.to_string();
47        assert!(s.contains("0.0.0.0:8080"));
48        assert!(s.contains("address in use"));
49    }
50
51    #[test]
52    fn io_error_renders() {
53        let io = std::io::Error::other("disk full");
54        let e: Error = io.into();
55        assert!(e.to_string().contains("disk full"));
56    }
57
58    #[test]
59    fn configuration_error_renders() {
60        let e = Error::Configuration("invalid port".into());
61        assert_eq!(e.to_string(), "server configuration: invalid port");
62    }
63}