Skip to main content

moq_net/
error.rs

1use crate::coding;
2
3/// A list of possible errors that can occur during the session.
4#[derive(thiserror::Error, Debug, Clone)]
5#[non_exhaustive]
6pub enum Error {
7	#[error("transport: {0}")]
8	Transport(String),
9
10	#[error(transparent)]
11	Decode(#[from] coding::DecodeError),
12
13	// TODO move to a ConnectError
14	#[error("unsupported versions")]
15	Version,
16
17	/// A required extension was not present
18	#[error("extension required")]
19	RequiredExtension,
20
21	/// An unexpected stream type was received
22	#[error("unexpected stream type")]
23	UnexpectedStream,
24
25	#[error(transparent)]
26	BoundsExceeded(#[from] coding::BoundsExceeded),
27
28	/// A duplicate ID was used
29	// The broadcast/track is a duplicate
30	#[error("duplicate")]
31	Duplicate,
32
33	// Cancel is returned when there are no more readers.
34	#[error("cancelled")]
35	Cancel,
36
37	/// It took too long to open or transmit a stream.
38	#[error("timeout")]
39	Timeout,
40
41	/// The group is older than the latest group and dropped.
42	#[error("old")]
43	Old,
44
45	// The application closes the stream with a code.
46	#[error("app code={0}")]
47	App(u16),
48
49	#[error("not found")]
50	NotFound,
51
52	/// A broadcast was requested that is neither announced nor served by a dynamic
53	/// router, so there is no route to it.
54	#[error("unroutable")]
55	Unroutable,
56
57	#[error("wrong frame size")]
58	WrongSize,
59
60	#[error("protocol violation")]
61	ProtocolViolation,
62
63	#[error("unauthorized")]
64	Unauthorized,
65
66	#[error("unexpected message")]
67	UnexpectedMessage,
68
69	#[error("unsupported")]
70	Unsupported,
71
72	#[error(transparent)]
73	Encode(#[from] coding::EncodeError),
74
75	#[error("too many parameters")]
76	TooManyParameters,
77
78	#[error("invalid role")]
79	InvalidRole,
80
81	#[error("unknown ALPN: {0}")]
82	UnknownAlpn(String),
83
84	#[error("dropped")]
85	Dropped,
86
87	#[error("closed")]
88	Closed,
89
90	/// The cached frame has been evicted due to the group size limit.
91	#[error("cache full")]
92	CacheFull,
93
94	/// A frame declared a payload size larger than the receiver accepts.
95	#[error("frame too large")]
96	FrameTooLarge,
97
98	/// A remote error received via a stream/session reset code.
99	#[error("remote error: code={0}")]
100	Remote(u32),
101}
102
103impl Error {
104	/// An integer code that is sent over the wire.
105	pub fn to_code(&self) -> u32 {
106		match self {
107			Self::Cancel => 0,
108			Self::RequiredExtension => 1,
109			Self::Old => 2,
110			Self::Timeout => 3,
111			Self::Transport(_) => 4,
112			Self::Decode(_) => 5,
113			Self::Unauthorized => 6,
114			Self::Version => 9,
115			Self::UnexpectedStream => 10,
116			Self::BoundsExceeded(_) => 11,
117			Self::Duplicate => 12,
118			Self::NotFound => 13,
119			Self::WrongSize => 14,
120			Self::ProtocolViolation => 15,
121			Self::UnexpectedMessage => 16,
122			Self::Unsupported => 17,
123			Self::Encode(_) => 18,
124			Self::TooManyParameters => 19,
125			Self::InvalidRole => 20,
126			Self::UnknownAlpn(_) => 21,
127			Self::Dropped => 24,
128			Self::Closed => 25,
129			Self::CacheFull => 26,
130			Self::FrameTooLarge => 27,
131			// 28 (Decompress) and 29 (TimestampMismatch) are reserved on the dev branch;
132			// keep Unroutable at 30 so the wire code is identical across branches.
133			Self::Unroutable => 30,
134			Self::App(app) => *app as u32 + 64,
135			Self::Remote(code) => *code,
136		}
137	}
138
139	/// Convert a transport error into an [Error], decoding stream reset codes.
140	pub fn from_transport(err: impl web_transport_trait::Error) -> Self {
141		if let Some(code) = err.stream_error() {
142			return Self::Remote(code);
143		}
144
145		Self::Transport(err.to_string())
146	}
147}
148
149impl web_transport_trait::Error for Error {
150	fn session_error(&self) -> Option<(u32, String)> {
151		None
152	}
153}
154
155pub type Result<T> = std::result::Result<T, Error>;