Skip to main content

moq/
error.rs

1use std::sync::Arc;
2
3use crate::ffi;
4
5/// Status code returned by FFI functions.
6///
7/// Negative values indicate errors, zero indicates success,
8/// and positive values are valid resource handles.
9pub type Status = i32;
10
11/// Error types that can occur in the FFI layer.
12///
13/// Each error variant maps to a specific negative error code
14/// returned to C callers.
15#[derive(Debug, thiserror::Error, Clone)]
16#[non_exhaustive]
17pub enum Error {
18	/// Error from the underlying MoQ protocol layer.
19	#[error("moq error: {0}")]
20	Moq(#[from] moq_net::Error),
21
22	/// Error from the native helper layer (moq-native).
23	#[error("native error: {0}")]
24	Native(#[from] moq_native::Error),
25
26	/// URL parsing error.
27	#[error("url error: {0}")]
28	Url(#[from] url::ParseError),
29
30	/// UTF-8 string validation error.
31	#[error("utf8 error: {0}")]
32	Utf8(#[from] std::str::Utf8Error),
33
34	/// Connection establishment error.
35	#[error("connect error: {0}")]
36	Connect(Arc<anyhow::Error>),
37
38	/// Null or invalid pointer passed from C.
39	#[error("invalid pointer")]
40	InvalidPointer,
41
42	/// Invalid resource ID.
43	#[error("invalid id")]
44	InvalidId,
45
46	/// Resource not found.
47	#[error("not found")]
48	NotFound,
49
50	/// Session task not found.
51	#[error("session not found")]
52	SessionNotFound,
53
54	/// Origin producer not found.
55	#[error("origin not found")]
56	OriginNotFound,
57
58	/// Announcement not found.
59	#[error("announcement not found")]
60	AnnouncementNotFound,
61
62	/// Broadcast not found.
63	#[error("broadcast not found")]
64	BroadcastNotFound,
65
66	/// Catalog not found.
67	#[error("catalog not found")]
68	CatalogNotFound,
69
70	/// Media decoder not found.
71	#[error("media not found")]
72	MediaNotFound,
73
74	/// Track task not found.
75	#[error("track not found")]
76	TrackNotFound,
77
78	/// Group producer not found.
79	#[error("group not found")]
80	GroupNotFound,
81
82	/// Frame not found.
83	#[error("frame not found")]
84	FrameNotFound,
85
86	/// Unknown media format specified.
87	#[error("unknown format: {0}")]
88	UnknownFormat(String),
89
90	/// Media decoder initialization failed.
91	#[error("init failed: {0}")]
92	InitFailed(Arc<anyhow::Error>),
93
94	/// Media frame decode failed.
95	#[error("decode failed: {0}")]
96	DecodeFailed(Arc<anyhow::Error>),
97
98	/// Timestamp value overflow.
99	#[error("timestamp overflow")]
100	TimestampOverflow(#[from] moq_net::TimeOverflow),
101
102	/// Log level parsing error.
103	#[error("level error: {0}")]
104	Level(Arc<tracing::metadata::ParseLevelError>),
105
106	/// Invalid error code conversion.
107	#[error("invalid code")]
108	InvalidCode,
109
110	/// Panic occurred in Rust code.
111	#[error("panic")]
112	Panic,
113
114	/// Session is offline.
115	#[error("offline")]
116	Offline,
117
118	/// Connection was rejected as unauthorized by the server.
119	#[error("unauthorized")]
120	Unauthorized,
121
122	/// Connection was forbidden by the server.
123	#[error("forbidden")]
124	Forbidden,
125
126	/// Error from the hang media layer.
127	#[error("hang error: {0}")]
128	Hang(#[from] hang::Error),
129
130	/// Error from the moq-mux consumer layer.
131	#[error("mux error: {0}")]
132	Mux(Arc<moq_mux::Error>),
133
134	/// Index out of bounds.
135	#[error("no index")]
136	NoIndex,
137
138	/// Null byte found in C string.
139	#[error("nul error")]
140	NulError(#[from] std::ffi::NulError),
141
142	/// Error from the moq-audio codec layer.
143	#[error("audio error: {0}")]
144	Audio(Arc<moq_audio::AudioError>),
145
146	/// Invalid JSON passed for an application catalog section.
147	#[error("json error: {0}")]
148	Json(Arc<serde_json::Error>),
149
150	/// Error from the moq-json snapshot/stream layer.
151	#[error("json track error: {0}")]
152	JsonTrack(Arc<moq_json::Error>),
153}
154
155impl From<moq_json::Error> for Error {
156	fn from(err: moq_json::Error) -> Self {
157		match err {
158			moq_json::Error::Net(e) => Error::Moq(e),
159			e => Error::JsonTrack(Arc::new(e)),
160		}
161	}
162}
163
164impl From<serde_json::Error> for Error {
165	fn from(err: serde_json::Error) -> Self {
166		Error::Json(Arc::new(err))
167	}
168}
169
170impl From<moq_audio::AudioError> for Error {
171	fn from(err: moq_audio::AudioError) -> Self {
172		Error::Audio(Arc::new(err))
173	}
174}
175
176impl From<tracing::metadata::ParseLevelError> for Error {
177	fn from(err: tracing::metadata::ParseLevelError) -> Self {
178		Error::Level(Arc::new(err))
179	}
180}
181
182impl From<moq_mux::Error> for Error {
183	fn from(err: moq_mux::Error) -> Self {
184		match err {
185			moq_mux::Error::Moq(e) => Error::Moq(e),
186			moq_mux::Error::Hang(e) => Error::Hang(e),
187			e => Error::Mux(Arc::new(e)),
188		}
189	}
190}
191
192impl ffi::ReturnCode for Error {
193	fn error(&self) -> Option<&Error> {
194		Some(self)
195	}
196
197	fn code(&self) -> i32 {
198		match self {
199			Error::Moq(_) => -2,
200			Error::Url(_) => -3,
201			Error::Utf8(_) => -4,
202			Error::Connect(_) => -5,
203			Error::InvalidPointer => -6,
204			Error::InvalidId => -7,
205			Error::NotFound => -8,
206			Error::UnknownFormat(_) => -9,
207			Error::InitFailed(_) => -10,
208			Error::DecodeFailed(_) => -11,
209			Error::TimestampOverflow(_) => -13,
210			Error::Level(_) => -14,
211			Error::InvalidCode => -15,
212			Error::Panic => -16,
213			Error::Offline => -17,
214			Error::Hang(_) => -18,
215			Error::NoIndex => -19,
216			Error::NulError(_) => -20,
217			Error::SessionNotFound => -21,
218			Error::OriginNotFound => -22,
219			Error::AnnouncementNotFound => -23,
220			Error::BroadcastNotFound => -24,
221			Error::CatalogNotFound => -25,
222			Error::MediaNotFound => -26,
223			Error::TrackNotFound => -27,
224			Error::FrameNotFound => -28,
225			Error::Mux(_) => -29,
226			Error::Audio(_) => -30,
227			Error::GroupNotFound => -31,
228			Error::Native(_) => -32,
229			Error::Unauthorized => -33,
230			Error::Forbidden => -34,
231			Error::Json(_) => -35,
232			Error::JsonTrack(_) => -36,
233		}
234	}
235}