Skip to main content

tightbeam/
error.rs

1#[cfg(not(feature = "std"))]
2extern crate alloc;
3#[cfg(not(feature = "std"))]
4use alloc::vec::Vec;
5
6use crate::spki::ObjectIdentifier;
7use crate::Version;
8
9#[cfg(feature = "derive")]
10use crate::Errorizable;
11
12/// A specialized Result type for TightBeam operations
13pub type Result<T> = core::result::Result<T, TightBeamError>;
14
15/// A specialized Result type for compression operations
16#[cfg(feature = "compress")]
17pub type CompressionResult<T> = core::result::Result<T, CompressionError>;
18
19/// Error indicating a mismatch between received and expected values
20#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
21pub struct ReceivedExpectedError<Received, Expected> {
22	pub received: Received,
23	pub expected: Expected,
24}
25
26impl<Received, Expected> From<(Received, Expected)> for ReceivedExpectedError<Received, Expected> {
27	fn from((received, expected): (Received, Expected)) -> Self {
28		Self { received, expected }
29	}
30}
31
32impl<Received: core::fmt::Debug, Expected: core::fmt::Debug> core::fmt::Display
33	for ReceivedExpectedError<Received, Expected>
34{
35	fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
36		write!(f, "expected {:?}, got {:?}", self.expected, self.received)
37	}
38}
39
40#[cfg(feature = "compress")]
41#[cfg_attr(feature = "derive", derive(Errorizable))]
42#[derive(Debug)]
43pub enum CompressionError {
44	#[cfg(feature = "zstd")]
45	#[cfg_attr(feature = "derive", error("ZSTD compression/decompression error: {0}"))]
46	#[cfg_attr(feature = "derive", from)]
47	#[cfg_attr(feature = "derive", source)]
48	ZSTD(zeekstd::Error),
49
50	#[cfg(feature = "std")]
51	#[cfg_attr(feature = "derive", error("I/O error during compression/decompression: {0}"))]
52	#[cfg_attr(feature = "derive", from)]
53	#[cfg_attr(feature = "derive", source)]
54	IO(std::io::Error),
55
56	#[cfg(feature = "zstd")]
57	#[cfg_attr(feature = "derive", error("decompressed output exceeds the {0}-byte limit"))]
58	OutputLimitExceeded(usize),
59}
60
61#[cfg(all(feature = "compress", not(feature = "derive")))]
62impl core::fmt::Display for CompressionError {
63	fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
64		match self {
65			#[cfg(feature = "zstd")]
66			CompressionError::ZSTD(e) => write!(f, "ZSTD compression/decompression error: {e}"),
67			#[cfg(feature = "std")]
68			CompressionError::IO(e) => write!(f, "I/O error during compression/decompression: {e}"),
69			#[cfg(feature = "zstd")]
70			CompressionError::OutputLimitExceeded(limit) => {
71				write!(f, "decompressed output exceeds the {limit}-byte limit")
72			}
73			// Without zstd/std the enum is uninhabited; this arm is
74			// unreachable but keeps the match exhaustive for the compiler.
75			#[cfg(not(any(feature = "zstd", feature = "std")))]
76			_ => write!(f, ""),
77		}
78	}
79}
80
81/// Trait for injected faults in testing
82#[cfg(feature = "testing-fault")]
83pub trait InjectedError: core::fmt::Debug + core::fmt::Display + Send + Sync {}
84
85// Blanket implementation for any type meeting the requirements
86#[cfg(feature = "testing-fault")]
87impl<T> InjectedError for T where T: core::fmt::Debug + core::fmt::Display + Send + Sync {}
88
89#[cfg_attr(feature = "derive", derive(Errorizable))]
90#[derive(Debug)]
91pub enum TightBeamError {
92	/// Error from the matrix implementation
93	#[cfg_attr(feature = "derive", error("Matrix error: {0}"))]
94	#[cfg_attr(feature = "derive", from)]
95	#[cfg_attr(feature = "derive", source)]
96	MatrixError(crate::matrix::MatrixError),
97
98	#[cfg(feature = "router")]
99	#[cfg_attr(feature = "derive", error("Route error: {0}"))]
100	#[cfg_attr(feature = "derive", from)]
101	#[cfg_attr(feature = "derive", source)]
102	RouterError(crate::router::RouterError),
103
104	/// Error from the message builder
105	#[cfg(feature = "builder")]
106	#[cfg_attr(feature = "derive", error("Build error: {0}"))]
107	#[cfg_attr(feature = "derive", from)]
108	#[cfg_attr(feature = "derive", source)]
109	BuildError(crate::builder::error::BuildError),
110
111	/// StandardError
112	#[cfg(feature = "standards")]
113	#[cfg_attr(feature = "derive", error("Standard error: {0}"))]
114	#[cfg_attr(feature = "derive", from)]
115	#[cfg_attr(feature = "derive", source)]
116	StandardError(crate::standards::error::StandardError),
117
118	#[cfg(feature = "colony")]
119	#[cfg_attr(feature = "derive", error("Hive error: {0}"))]
120	#[cfg_attr(feature = "derive", from)]
121	#[cfg_attr(feature = "derive", source)]
122	HiveError(crate::colony::hive::HiveError),
123
124	#[cfg(feature = "colony")]
125	#[cfg_attr(feature = "derive", error("Worker relay error: {0}"))]
126	#[cfg_attr(feature = "derive", from)]
127	#[cfg_attr(feature = "derive", source)]
128	WorkerRelay(crate::colony::worker::WorkerRelayError),
129
130	#[cfg(feature = "std")]
131	/// I/O error
132	#[cfg_attr(feature = "derive", error("I/O error: {0}"))]
133	#[cfg_attr(feature = "derive", from)]
134	#[cfg_attr(feature = "derive", source)]
135	IoError(std::io::Error),
136
137	#[cfg(feature = "std")]
138	/// Lock poisoned
139	#[cfg_attr(feature = "derive", error("Lock poisoned"))]
140	LockPoisoned,
141
142	/// Invalid or unsupported algorithm identifier
143	#[cfg_attr(feature = "derive", error("Invalid or unsupported object identifier: {0}"))]
144	InvalidOID(crate::der::oid::Error),
145
146	/// Error during signature verification or generation
147	#[cfg(feature = "signature")]
148	#[cfg_attr(feature = "derive", error("Signature verification or generation error: {0}"))]
149	#[cfg_attr(feature = "derive", from)]
150	#[cfg_attr(feature = "derive", source)]
151	SignatureError(crate::crypto::sign::Error),
152
153	/// Error from elliptic curve operations
154	#[cfg(feature = "signature")]
155	#[cfg_attr(feature = "derive", error("Elliptic curve error: {0}"))]
156	#[cfg_attr(feature = "derive", from)]
157	#[cfg_attr(feature = "derive", source)]
158	EllipticCurveError(crate::crypto::sign::elliptic_curve::Error),
159
160	/// Error during serialization
161	#[cfg_attr(feature = "derive", error("Serialization error: {0}"))]
162	#[cfg_attr(feature = "derive", from)]
163	#[cfg_attr(feature = "derive", source)]
164	SerializationError(crate::der::Error),
165
166	/// Error during compression or decompression
167	#[cfg(feature = "compress")]
168	#[cfg_attr(feature = "derive", error("Compression error: {0}"))]
169	#[cfg_attr(feature = "derive", from)]
170	#[cfg_attr(feature = "derive", source)]
171	CompressionError(CompressionError),
172
173	/// Error during handshake operations
174	#[cfg(feature = "transport")]
175	#[cfg_attr(feature = "derive", error("Handshake error: {0}"))]
176	#[cfg_attr(feature = "derive", from)]
177	#[cfg_attr(feature = "derive", source)]
178	HandshakeError(crate::transport::handshake::HandshakeError),
179
180	#[cfg(feature = "transport")]
181	#[cfg_attr(feature = "derive", error("Transport error: {0}"))]
182	#[cfg_attr(feature = "derive", from)]
183	#[cfg_attr(feature = "derive", source)]
184	TransportError(crate::transport::error::TransportError),
185
186	/// Unsupported protocol version
187	#[cfg_attr(
188		feature = "derive",
189		error("Unsupported protocol version: expected {expected:?}, got {received:?}")
190	)]
191	UnsupportedVersion(ReceivedExpectedError<Version, Version>),
192
193	/// Error during testing operations
194	#[cfg(feature = "testing")]
195	#[cfg_attr(feature = "derive", error("Testing error: {0}"))]
196	#[cfg_attr(feature = "derive", from)]
197	#[cfg_attr(feature = "derive", source)]
198	TestingError(crate::testing::error::TestingError),
199
200	/// Error during URN validation
201	#[cfg_attr(feature = "derive", error("URN validation error: {0}"))]
202	#[cfg_attr(feature = "derive", from)]
203	#[cfg_attr(feature = "derive", source)]
204	UrnValidationError(crate::utils::urn::UrnValidationError),
205
206	/// Error during encryption or decryption
207	#[cfg(feature = "aead")]
208	#[cfg_attr(feature = "derive", error("Encryption or decryption error: {0}"))]
209	#[cfg_attr(feature = "derive", from)]
210	#[cfg_attr(feature = "derive", source)]
211	EncryptionError(crate::crypto::aead::Error),
212
213	/// Invalid key length for cryptographic operations
214	#[cfg(feature = "aead")]
215	#[cfg_attr(feature = "derive", error("Invalid key length: {0}"))]
216	#[cfg_attr(feature = "derive", from)]
217	#[cfg_attr(feature = "derive", source)]
218	InvalidKeyLength(crypto_common::InvalidLength),
219
220	/// Error during ECIES operations
221	#[cfg(feature = "ecies")]
222	#[cfg_attr(feature = "derive", error("ECIES error: {0}"))]
223	#[cfg_attr(feature = "derive", from)]
224	#[cfg_attr(feature = "derive", source)]
225	EciesError(crate::crypto::ecies::EciesError),
226
227	#[cfg(feature = "crypto")]
228	#[cfg_attr(feature = "derive", error("Crypto policy error: {0}"))]
229	#[cfg_attr(feature = "derive", from)]
230	#[cfg_attr(feature = "derive", source)]
231	CryptoPolicyError(crate::crypto::policy::CryptoPolicyError),
232
233	/// Error during certificate validation
234	#[cfg(feature = "x509")]
235	#[cfg_attr(feature = "derive", error("Certificate validation error: {0}"))]
236	#[cfg_attr(feature = "derive", from)]
237	#[cfg_attr(feature = "derive", source)]
238	CertificateValidationError(crate::crypto::x509::error::CertificateValidationError),
239
240	#[cfg(feature = "kdf")]
241	#[cfg_attr(feature = "derive", error("Key derivation error: {0}"))]
242	#[cfg_attr(feature = "derive", from)]
243	#[cfg_attr(feature = "derive", source)]
244	KeyDerivationError(crate::crypto::kdf::KdfError),
245
246	/// Error from key provider operations
247	#[cfg(feature = "crypto")]
248	#[cfg_attr(feature = "derive", error("Key provider error: {0}"))]
249	#[cfg_attr(feature = "derive", from)]
250	#[cfg_attr(feature = "derive", source)]
251	KeyError(crate::crypto::key::KeyError),
252
253	/// Secret material was unavailable
254	#[cfg(feature = "crypto")]
255	#[cfg_attr(feature = "derive", error("Secret unavailable: {0}"))]
256	#[cfg_attr(feature = "derive", from)]
257	#[cfg_attr(feature = "derive", source)]
258	SecretUnavailable(crate::crypto::secret::SecretError),
259
260	/// Error obtaining random bytes from the OS
261	#[cfg(feature = "random")]
262	#[cfg_attr(feature = "derive", error("OS random number generator error: {0}"))]
263	#[cfg_attr(feature = "derive", from)]
264	#[cfg_attr(feature = "derive", source)]
265	OsRngError(rand_core::Error),
266
267	/// Error during SPKI operations
268	#[cfg(feature = "x509")]
269	#[cfg_attr(feature = "derive", error("SPKI error: {0}"))]
270	#[cfg_attr(feature = "derive", from)]
271	#[cfg_attr(feature = "derive", source)]
272	SpkiError(crate::spki::Error),
273
274	/// Error during X.509 certificate building
275	#[cfg(feature = "builder")]
276	#[cfg_attr(feature = "derive", error("X.509 builder error: {0}"))]
277	#[cfg_attr(feature = "derive", from)]
278	#[cfg_attr(feature = "derive", source)]
279	X509BuilderError(x509_cert::builder::Error),
280
281	/// Error receiving from channel with timeout
282	#[cfg(feature = "std")]
283	#[cfg_attr(feature = "derive", error("Channel receive timeout error"))]
284	RecvTimeoutError,
285
286	/// Error decoding signature from bytes
287	#[cfg(feature = "signature")]
288	#[cfg_attr(feature = "derive", error("Signature encoding error"))]
289	SignatureEncodingError,
290
291	/// Invalid metadata
292	#[cfg_attr(feature = "derive", error("Invalid metadata"))]
293	InvalidMetadata,
294
295	/// Invalid message body
296	#[cfg_attr(feature = "derive", error("Invalid message body"))]
297	InvalidBody,
298
299	/// Invalid overflow value
300	#[cfg_attr(feature = "derive", error("Invalid overflow value"))]
301	InvalidOverflowValue,
302
303	/// Invalid order
304	#[cfg_attr(feature = "derive", error("Invalid order"))]
305	InvalidOrder,
306
307	// Missing order
308	#[cfg_attr(feature = "derive", error("Missing order"))]
309	MissingOrder,
310
311	/// Missing inflator
312	#[cfg_attr(feature = "derive", error("Missing inflator"))]
313	MissingInflator,
314
315	/// Missing feature
316	#[cfg_attr(feature = "derive", error("Missing feature: {0}"))]
317	MissingFeature(&'static str),
318
319	/// Missing priority
320	#[cfg_attr(feature = "derive", error("Missing priority"))]
321	MissingPriority,
322
323	/// Missing response
324	#[cfg_attr(feature = "derive", error("Missing response"))]
325	MissingResponse,
326
327	/// Channel closed: the receiving end was dropped before the send
328	#[cfg_attr(feature = "derive", error("Channel closed"))]
329	ChannelClosed,
330
331	/// Signature is missing
332	#[cfg(feature = "signature")]
333	#[cfg_attr(feature = "derive", error("Missing signature"))]
334	MissingSignature,
335
336	/// Signature info is missing
337	#[cfg(feature = "signature")]
338	#[cfg_attr(feature = "derive", error("Missing signature info"))]
339	MissingSignatureInfo,
340
341	/// Missing Encryption Info
342	#[cfg(feature = "aead")]
343	#[cfg_attr(feature = "derive", error("Missing encryption info"))]
344	MissingEncryptionInfo,
345
346	/// AEAD nonce length does not match the cipher's nonce size
347	#[cfg(feature = "aead")]
348	#[cfg_attr(
349		feature = "derive",
350		error("Invalid AEAD nonce length: expected {expected:?}, got {received:?}")
351	)]
352	InvalidNonceLength(ReceivedExpectedError<usize, usize>),
353
354	/// Missing Integrity Info
355	#[cfg(feature = "digest")]
356	#[cfg_attr(feature = "derive", error("Missing integrity info"))]
357	MissingDigestInfo,
358
359	/// Missing Compression Info
360	#[cfg_attr(feature = "derive", error("Missing compression info"))]
361	MissingCompressedData,
362
363	/// Invalid algorithm for the message profile
364	#[cfg_attr(feature = "derive", error("Invalid algorithm for message profile"))]
365	InvalidAlgorithm,
366
367	/// Unexpected algorithm for the message profile
368	#[cfg_attr(
369		feature = "derive",
370		error("Unexpected algorithm for message profile: expected {expected:?}, got {received:?}")
371	)]
372	UnexpectedAlgorithm(ReceivedExpectedError<ObjectIdentifier, ObjectIdentifier>),
373
374	/// Missing or invalid configuration
375	#[cfg_attr(feature = "derive", error("Missing configuration"))]
376	MissingConfiguration,
377
378	/// Operation not supported by this implementation
379	#[cfg_attr(feature = "derive", error("Unsupported operation"))]
380	UnsupportedOperation,
381
382	/// Hive already established
383	#[cfg(feature = "colony")]
384	#[cfg_attr(feature = "derive", error("Hive already established"))]
385	AlreadyEstablished,
386
387	/// Task join error
388	#[cfg(feature = "colony")]
389	#[cfg_attr(feature = "derive", error("Task join failed"))]
390	JoinError,
391
392	/// Multiple errors collected together
393	#[cfg_attr(feature = "derive", error("Multiple errors occurred: {0:?}"))]
394	Sequence(Vec<TightBeamError>),
395
396	/// Injected fault for testing (any error type)
397	#[cfg(feature = "testing-fault")]
398	#[cfg_attr(feature = "derive", error("Injected fault: {0}"))]
399	InjectedFault(Box<dyn InjectedError>),
400}
401
402#[cfg(all(feature = "colony", not(feature = "derive")))]
403impl From<crate::colony::WorkerRelayError> for TightBeamError {
404	fn from(err: crate::colony::WorkerRelayError) -> Self {
405		TightBeamError::WorkerRelay(err)
406	}
407}
408
409#[cfg(not(feature = "derive"))]
410impl core::fmt::Display for TightBeamError {
411	fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
412		match self {
413			TightBeamError::SerializationError(err) => write!(f, "Serialization error: {err}"),
414			TightBeamError::MatrixError(err) => write!(f, "Matrix error: {err}"),
415			#[cfg(feature = "std")]
416			TightBeamError::IoError(err) => write!(f, "I/O error: {err}"),
417			#[cfg(feature = "crypto")]
418			TightBeamError::CryptoPolicyError(err) => write!(f, "Crypto policy error: {err}"),
419			#[cfg(feature = "x509")]
420			TightBeamError::CertificateValidationError(err) => {
421				write!(f, "Certificate validation error: {err}")
422			}
423			#[cfg(feature = "router")]
424			TightBeamError::RouterError(err) => write!(f, "Route error: {err}"),
425			TightBeamError::InvalidMetadata => write!(f, "Invalid metadata"),
426			TightBeamError::InvalidBody => write!(f, "Invalid message body"),
427			TightBeamError::InvalidOID(err) => {
428				write!(f, "Invalid or unsupported object identifier: {err}")
429			}
430			TightBeamError::InvalidOverflowValue => write!(f, "Invalid overflow value"),
431			TightBeamError::InvalidOrder => write!(f, "Invalid order"),
432			TightBeamError::MissingInflator => write!(f, "Missing inflator"),
433			TightBeamError::MissingOrder => write!(f, "Missing order"),
434			TightBeamError::MissingPriority => write!(f, "Missing priority"),
435			TightBeamError::MissingResponse => write!(f, "Missing response"),
436			TightBeamError::ChannelClosed => write!(f, "Channel closed"),
437			TightBeamError::MissingFeature(feature) => write!(f, "Missing feature: {feature}"),
438			TightBeamError::MissingConfiguration => write!(f, "Missing configuration"),
439			TightBeamError::UnsupportedOperation => write!(f, "Unsupported operation"),
440			#[cfg(feature = "transport")]
441			TightBeamError::HandshakeError(err) => write!(f, "Handshake error: {err}"),
442			#[cfg(feature = "colony")]
443			TightBeamError::HiveError(err) => write!(f, "Hive error: {err}"),
444			#[cfg(feature = "std")]
445			TightBeamError::LockPoisoned => write!(f, "Lock poisoned"),
446			#[cfg(feature = "standards")]
447			TightBeamError::StandardError(err) => write!(f, "Standard error: {err}"),
448			#[cfg(feature = "random")]
449			TightBeamError::OsRngError(err) => write!(f, "OS random number generator error: {err}"),
450			#[cfg(feature = "x509")]
451			TightBeamError::SpkiError(err) => write!(f, "SPKI error: {err}"),
452			#[cfg(feature = "builder")]
453			TightBeamError::X509BuilderError(err) => write!(f, "X.509 builder error: {err}"),
454			#[cfg(feature = "std")]
455			TightBeamError::RecvTimeoutError => write!(f, "Channel receive timeout error"),
456			#[cfg(feature = "aead")]
457			TightBeamError::EncryptionError(err) => {
458				write!(f, "Encryption or decryption error: {err}")
459			}
460			#[cfg(feature = "aead")]
461			TightBeamError::InvalidKeyLength(_) => {
462				write!(f, "Invalid key length")
463			}
464			#[cfg(feature = "ecies")]
465			TightBeamError::EciesError(err) => write!(f, "ECIES error: {err}"),
466			#[cfg(feature = "kdf")]
467			TightBeamError::KeyDerivationError(err) => write!(f, "Key derivation error: {err}"),
468			#[cfg(feature = "signature")]
469			TightBeamError::SignatureError(err) => {
470				write!(f, "Signature verification or generation error: {err}")
471			}
472			#[cfg(feature = "signature")]
473			TightBeamError::EllipticCurveError(_) => write!(f, "Elliptic curve error"),
474			#[cfg(feature = "signature")]
475			TightBeamError::SignatureEncodingError => write!(f, "Signature encoding error"),
476			#[cfg(feature = "crypto")]
477			TightBeamError::KeyError(err) => write!(f, "Key provider error: {err}"),
478			#[cfg(feature = "crypto")]
479			TightBeamError::SecretUnavailable(err) => write!(f, "Secret unavailable: {err}"),
480			#[cfg(feature = "digest")]
481			TightBeamError::MissingDigestInfo => write!(f, "Missing integrity info"),
482			#[cfg(feature = "aead")]
483			TightBeamError::MissingEncryptionInfo => write!(f, "Missing encryption info"),
484			#[cfg(feature = "aead")]
485			TightBeamError::InvalidNonceLength(err) => {
486				write!(
487					f,
488					"Invalid AEAD nonce length: expected {:?}, got {:?}",
489					err.expected, err.received
490				)
491			}
492			#[cfg(feature = "signature")]
493			TightBeamError::MissingSignatureInfo => write!(f, "Missing signature info"),
494			#[cfg(feature = "signature")]
495			TightBeamError::MissingSignature => write!(f, "Missing signature"),
496			TightBeamError::MissingCompressedData => write!(f, "Missing compression info"),
497			TightBeamError::InvalidAlgorithm => write!(f, "Invalid algorithm for message profile"),
498			TightBeamError::UnexpectedAlgorithm(err) => {
499				write!(
500					f,
501					"Unexpected algorithm for message profile: expected {:?}, got {:?}",
502					err.expected, err.received
503				)
504			}
505			#[cfg(feature = "compress")]
506			TightBeamError::CompressionError(err) => write!(f, "Compression error: {err}"),
507			TightBeamError::Sequence(errors) => {
508				write!(f, "Multiple errors: ")?;
509				for (i, error) in errors.iter().enumerate() {
510					if i > 0 {
511						write!(f, "; ")?;
512					}
513					write!(f, "{error}")?;
514				}
515				Ok(())
516			}
517			#[cfg(feature = "colony")]
518			TightBeamError::AlreadyEstablished => write!(f, "Hive already established"),
519			#[cfg(feature = "colony")]
520			TightBeamError::JoinError => write!(f, "Task join failed"),
521			TightBeamError::UnsupportedVersion(err) => {
522				write!(
523					f,
524					"Unsupported protocol version: expected {:?}, got {:?}",
525					err.expected, err.received
526				)
527			}
528			#[cfg(feature = "testing")]
529			TightBeamError::TestingError(err) => write!(f, "Testing error: {err}"),
530			TightBeamError::UrnValidationError(err) => write!(f, "URN validation error: {err}"),
531			#[cfg(feature = "testing-fault")]
532			TightBeamError::InjectedFault(err) => write!(f, "Injected fault: {err}"),
533		}
534	}
535}
536
537#[cfg(feature = "std")]
538crate::impl_from!(std::string::FromUtf8Error => TightBeamError::IoError via |err| std::io::Error::new(std::io::ErrorKind::InvalidData, err));
539#[cfg(feature = "std")]
540crate::impl_from!(std::net::AddrParseError => TightBeamError::IoError via |err| std::io::Error::new(std::io::ErrorKind::InvalidInput, err));
541
542// ============================================================================
543// Non-derive From implementations
544// When `derive` feature is disabled, these provide the From impls that would
545// otherwise be generated by the Errorizable derive macro's #[from] attribute.
546// ============================================================================
547
548#[cfg(not(feature = "derive"))]
549crate::impl_from!(der::Error => TightBeamError::SerializationError);
550#[cfg(not(feature = "derive"))]
551crate::impl_from!(crate::matrix::MatrixError => TightBeamError::MatrixError);
552#[cfg(not(feature = "derive"))]
553crate::impl_from!(crate::utils::urn::UrnValidationError => TightBeamError::UrnValidationError);
554#[cfg(all(feature = "crypto", not(feature = "derive")))]
555crate::impl_from!(crate::crypto::policy::CryptoPolicyError => TightBeamError::CryptoPolicyError);
556#[cfg(all(feature = "kdf", not(feature = "derive")))]
557crate::impl_from!(crate::crypto::kdf::KdfError => TightBeamError::KeyDerivationError);
558#[cfg(all(feature = "crypto", not(feature = "derive")))]
559crate::impl_from!(crate::crypto::key::KeyError => TightBeamError::KeyError);
560#[cfg(all(feature = "crypto", not(feature = "derive")))]
561crate::impl_from!(crate::crypto::secret::SecretError => TightBeamError::SecretUnavailable);
562
563#[cfg(all(feature = "std", not(feature = "derive")))]
564crate::impl_from!(std::io::Error => TightBeamError::IoError);
565
566#[cfg(all(feature = "router", not(feature = "derive")))]
567crate::impl_from!(crate::router::RouterError => TightBeamError::RouterError);
568
569#[cfg(all(feature = "builder", not(feature = "derive")))]
570crate::impl_from!(crate::builder::error::BuildError => TightBeamError::BuildError);
571
572#[cfg(all(feature = "standards", not(feature = "derive")))]
573crate::impl_from!(crate::standards::error::StandardError => TightBeamError::StandardError);
574
575#[cfg(all(feature = "colony", not(feature = "derive")))]
576crate::impl_from!(crate::colony::hive::HiveError => TightBeamError::HiveError);
577#[cfg(all(feature = "colony", not(feature = "derive")))]
578crate::impl_from!(crate::colony::worker::WorkerRelayError => TightBeamError::WorkerRelay);
579
580#[cfg(all(feature = "transport", not(feature = "derive")))]
581crate::impl_from!(crate::transport::handshake::HandshakeError => TightBeamError::HandshakeError);
582#[cfg(all(feature = "transport", not(feature = "derive")))]
583crate::impl_from!(crate::transport::error::TransportError => TightBeamError::TransportError);
584
585#[cfg(all(feature = "random", not(feature = "derive")))]
586crate::impl_from!(rand_core::Error => TightBeamError::OsRngError);
587
588#[cfg(all(feature = "x509", not(feature = "derive")))]
589crate::impl_from!(spki::Error => TightBeamError::SpkiError);
590#[cfg(all(feature = "builder", not(feature = "derive")))]
591crate::impl_from!(x509_cert::builder::Error => TightBeamError::X509BuilderError);
592
593#[cfg(all(feature = "compress", not(feature = "derive")))]
594crate::impl_from!(CompressionError => TightBeamError::CompressionError);
595#[cfg(all(feature = "std", feature = "compress", not(feature = "derive")))]
596crate::impl_from!(std::io::Error => CompressionError::IO);
597
598#[cfg(all(feature = "aead", not(feature = "derive")))]
599crate::impl_from!(aead::Error => TightBeamError::EncryptionError);
600#[cfg(all(feature = "aead", not(feature = "derive")))]
601crate::impl_from!(crypto_common::InvalidLength => TightBeamError::InvalidKeyLength);
602
603#[cfg(all(feature = "ecies", not(feature = "derive")))]
604crate::impl_from!(crate::crypto::ecies::EciesError => TightBeamError::EciesError);
605
606#[cfg(all(feature = "signature", not(feature = "derive")))]
607crate::impl_from!(signature::Error => TightBeamError::SignatureError);
608#[cfg(all(feature = "signature", not(feature = "derive")))]
609crate::impl_from!(crate::crypto::sign::elliptic_curve::Error => TightBeamError::EllipticCurveError);
610
611#[cfg(all(feature = "zstd", not(feature = "derive")))]
612crate::impl_from!(zeekstd::Error => TightBeamError::CompressionError via CompressionError::ZSTD);
613#[cfg(all(feature = "zstd", not(feature = "derive")))]
614crate::impl_from!(zeekstd::Error => CompressionError::ZSTD);
615#[cfg(all(feature = "testing", not(feature = "derive")))]
616crate::impl_from!(crate::testing::error::TestingError => TightBeamError::TestingError);
617#[cfg(all(feature = "std", not(feature = "derive")))]
618crate::impl_from!(std::sync::mpsc::RecvTimeoutError => TightBeamError::RecvTimeoutError discard);
619
620#[cfg(not(feature = "derive"))]
621impl core::error::Error for TightBeamError {}
622#[cfg(all(feature = "compress", not(feature = "derive")))]
623impl core::error::Error for CompressionError {}
624
625// Generic type to unit variant - requires manual impl due to generic T
626#[cfg(feature = "std")]
627impl<T> From<std::sync::PoisonError<T>> for TightBeamError {
628	fn from(_: std::sync::PoisonError<T>) -> Self {
629		TightBeamError::LockPoisoned
630	}
631}
632
633#[cfg(all(test, feature = "derive", feature = "std"))]
634mod tests {
635	use super::*;
636
637	#[test]
638	fn source_annotated_wrappers_expose_their_cause() {
639		let err = TightBeamError::from(crate::matrix::MatrixError::InvalidN(0));
640
641		let source = core::error::Error::source(&err);
642
643		assert!(matches!(err, TightBeamError::MatrixError(_)));
644		assert!(source.is_some());
645	}
646
647	#[test]
648	fn unit_variants_have_no_source() {
649		let err = TightBeamError::InvalidBody;
650
651		assert!(core::error::Error::source(&err).is_none());
652	}
653}