Skip to main content

tuwunel_service/fetcher/
error.rs

1//! Internal failure reporting for federation fetches.
2//!
3//! Failures remain cloneable for broadcast to coalesced callers and retain the
4//! servers actually contacted for operator-facing diagnostics.
5
6use std::fmt;
7
8use ruma::OwnedServerName;
9use tuwunel_core::{err, smallvec::SmallVec};
10
11/// Servers contacted before a fetch gave up.
12///
13/// Inline storage is sized to the common candidate-pool budget.
14pub(super) type Attempted = SmallVec<[OwnedServerName; 3]>;
15
16/// Describes why a coalesced fetch produced no response.
17///
18/// The cloneable value is broadcast to every subscriber and converted to
19/// [`tuwunel_core::Error`] at the public boundary.
20#[derive(Clone, Debug)]
21pub(super) enum Failure {
22	/// The permitted attempts or rounds ended without a valid response.
23	NotFound {
24		/// Servers actually contacted before the fetch stopped.
25		attempted: Attempted,
26	},
27
28	/// No candidate servers were available to try.
29	NoCandidates,
30
31	/// Caller interest vanished or worker communication closed before a response arrived.
32	Cancelled,
33}
34
35impl fmt::Display for Failure {
36	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37		match self {
38			| Self::NoCandidates => write!(f, "no candidate servers available"),
39			| Self::Cancelled => write!(f, "fetch cancelled"),
40			| Self::NotFound { attempted } => {
41				write!(f, "event not found on any of {} servers", attempted.len())
42			},
43		}
44	}
45}
46
47impl From<Failure> for tuwunel_core::Error {
48	fn from(failure: Failure) -> Self { err!(Request(NotFound("{failure}"))) }
49}