hick_compio/error.rs
1//! Public error types surfaced by the async API.
2
3use mdns_proto::{Name, error::RegisterServiceError as ProtoRegisterError};
4
5/// Errors raised while constructing or running an [`Endpoint`](crate::Endpoint).
6#[derive(Debug, thiserror::Error)]
7#[non_exhaustive]
8pub enum ServerError {
9 /// At least one of IPv4 / IPv6 must be enabled in
10 /// [`ServerOptions`](crate::ServerOptions).
11 #[error("ServerOptions has neither IPv4 nor IPv6 enabled")]
12 NoFamilyEnabled,
13
14 /// Binding the IPv4 multicast socket failed.
15 #[error("bind v4: {0}")]
16 BindV4(hick_udp::BindError),
17
18 /// Binding the IPv6 multicast socket failed.
19 #[error("bind v6: {0}")]
20 BindV6(hick_udp::BindError),
21
22 /// Joining the IPv4 mDNS multicast group failed. The socket bound but never
23 /// joined `224.0.0.251`, so it could send but not receive multicast — a
24 /// silent failure if ignored, hence surfaced at construction.
25 #[error("join v4: {0}")]
26 JoinV4(hick_udp::JoinError),
27
28 /// Joining the IPv6 mDNS multicast group failed (`ff02::fb`). See
29 /// [`Self::JoinV4`].
30 #[error("join v6: {0}")]
31 JoinV6(hick_udp::JoinError),
32
33 /// Wrapping the bound socket as an async UDP socket failed.
34 #[error("wrap socket: {0}")]
35 WrapSocket(std::io::Error),
36
37 /// I/O error during endpoint setup (e.g. setting non-blocking mode).
38 #[error(transparent)]
39 Io(#[from] std::io::Error),
40}
41
42/// Errors raised by
43/// [`Endpoint::register_service`](crate::Endpoint::register_service).
44#[derive(Debug, thiserror::Error)]
45#[non_exhaustive]
46pub enum RegisterError {
47 /// A service with the same instance name is already registered.
48 #[error("name already registered: {0}")]
49 NameAlreadyRegistered(Name),
50
51 /// The proto service pool is full.
52 #[error("service pool is full")]
53 StorageFull,
54
55 /// The driver task is no longer running.
56 #[error("endpoint driver is gone")]
57 DriverGone,
58
59 /// A future, currently-unknown variant of
60 /// [`ProtoRegisterError`](mdns_proto::error::RegisterServiceError) that
61 /// the conversion arm did not recognise. The wrapped string is the proto
62 /// error's `Display` output so callers can still log it meaningfully.
63 ///
64 /// Reachable only if `mdns-proto` grows a new `RegisterServiceError`
65 /// variant before this crate is updated to map it explicitly.
66 #[error("unexpected proto register error: {0}")]
67 Other(String),
68}
69
70impl From<ProtoRegisterError> for RegisterError {
71 fn from(e: ProtoRegisterError) -> Self {
72 // `ProtoRegisterError` is `#[non_exhaustive]`, so we MUST keep a
73 // catch-all. We enumerate every variant that exists today by name so
74 // adding a new proto variant trips a `// future:` review here rather
75 // than silently mis-mapping. Unknown future variants surface as
76 // [`Self::Other`] — preserving their `Display` — instead of being
77 // squashed into [`Self::StorageFull`] (which would lie about the
78 // failure mode).
79 match e {
80 ProtoRegisterError::NameAlreadyRegistered(n) => Self::NameAlreadyRegistered(n),
81 ProtoRegisterError::StorageFull(_) => Self::StorageFull,
82 // future: map any new ProtoRegisterError variant to a dedicated
83 // RegisterError arm here instead of falling through to `Other`.
84 other => Self::Other(other.to_string()),
85 }
86 }
87}
88
89/// Errors raised by [`Endpoint::start_query`](crate::Endpoint::start_query).
90#[derive(Debug, thiserror::Error)]
91#[non_exhaustive]
92pub enum StartQueryError {
93 /// The proto query pool is full.
94 #[error("query pool is full")]
95 StorageFull,
96
97 /// The driver task is no longer running.
98 #[error("endpoint driver is gone")]
99 DriverGone,
100}
101
102/// Errors raised by query cancellation and service unregistration.
103#[derive(Debug, thiserror::Error)]
104#[non_exhaustive]
105pub enum CancelError {
106 /// The driver task is no longer running.
107 #[error("endpoint driver is gone")]
108 DriverGone,
109}