Use Error trait from core 💬 by Caio 2 years ago (log)
This patch gets rid of the `anyhow` dependency in favor of `core::error::Error` and sets the MSRV to 1.81.0
This patch gets rid of the `anyhow` dependency in favor of `core::error::Error` and sets the MSRV to 1.81.0
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use core::fmt;
use alloc::boxed::Box;
#[derive(Debug)]
/// This type represents all possible errors operating a Foca instance.
pub enum Error {
/// Emitted whenever Foca receives a byte slice larger than
/// the configured limit ([`crate::Config::max_packet_size`]).
///
/// Doesn't affect Foca's state.
DataTooBig,
/// Attempt to [`crate::Foca::reuse_down_identity`] when not needed.
///
/// Doesn't affect Foca's state.
NotUndead,
/// Attempt to [`crate::Foca::change_identity`] with the same identity.
///
/// Doesn't affect Foca's state.
SameIdentity,
/// Expected to be connected when reaching this point.
/// Sentinel error to detect integration bugs.
///
/// Must not happen under normal circumstances.
NotConnected,
/// Reached the end of the probe cycle but expected
/// steps didn't happen. Bug in the runtime/scheduling
/// mechanism most likely.
///
/// Foca tries to resume normal operations after emitting this
/// error, but any occurance of it is a sign that something is
/// not behaving as expected
///
/// Must not happen under normal circumstances.
IncompleteProbeCycle,
/// Received data where the sender has the same
/// id as ourselves.
///
/// There's likely a member submitting wrong/manually-crafted
/// packets.
DataFromOurselves,
/// Data contains a message supposed to reach us via indirect
/// means.
///
/// There's likely a member submitting wrong/manually-crafted
/// packets.
IndirectForOurselves,
/// Data is in an unexpected format.
///
/// Doesn't affect Foca's state.
MalformedPacket,
/// Wraps [`crate::Codec`]'s `encode_*` failures.
/// Shouldn't happen under normal circumstances unless using a broken
/// codec.
///
/// Might have left Foca in a inconsistent state.
Encode(Box<dyn core::error::Error + Send>),
/// Wraps [`crate::Codec`]'s `decode_*` failures.
///
/// Can happen during normal operation when receiving junk data.
Decode(Box<dyn core::error::Error + Send>),
/// Wraps [`crate::BroadcastHandler`] failures.
///
/// Doesn't affect Foca's state.
CustomBroadcast(Box<dyn core::error::Error + Send>),
/// Configuration change not allowed.
///
/// Doesn't affact Foca's state.
///
/// See [`crate::Foca::set_config`].
InvalidConfig,
}
impl PartialEq for Error {
fn eq(&self, other: &Self) -> bool {
use alloc::string::ToString;
#[allow(clippy::match_same_arms)]
match (self, other) {
// Wrapped errors have to allocate to compare :(
// But PartialEq on an error type is mostly useful for tests
(Error::Encode(a), Error::Encode(b)) => a.to_string().eq(&b.to_string()),
(Error::Decode(a), Error::Decode(b)) => a.to_string().eq(&b.to_string()),
(Error::CustomBroadcast(a), Error::CustomBroadcast(b)) => {
a.to_string().eq(&b.to_string())
}
(Error::DataTooBig, Error::DataTooBig) => true,
(Error::NotConnected, Error::NotConnected) => true,
(Error::NotUndead, Error::NotUndead) => true,
(Error::SameIdentity, Error::SameIdentity) => true,
(Error::IncompleteProbeCycle, Error::IncompleteProbeCycle) => true,
(Error::DataFromOurselves, Error::DataFromOurselves) => true,
(Error::IndirectForOurselves, Error::IndirectForOurselves) => true,
(Error::MalformedPacket, Error::MalformedPacket) => true,
(Error::InvalidConfig, Error::InvalidConfig) => true,
// Instead of a catch-all here, we explicitly enumerate our variants
// so that when/if new errors are added we don't silently introduce
// a bug
(Error::Encode(_), _) => false,
(Error::Decode(_), _) => false,
(Error::CustomBroadcast(_), _) => false,
(Error::DataTooBig, _) => false,
(Error::NotConnected, _) => false,
(Error::NotUndead, _) => false,
(Error::SameIdentity, _) => false,
(Error::IncompleteProbeCycle, _) => false,
(Error::DataFromOurselves, _) => false,
(Error::IndirectForOurselves, _) => false,
(Error::MalformedPacket, _) => false,
(Error::InvalidConfig, _) => false,
}
}
}
impl fmt::Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
#[allow(clippy::match_same_arms)]
match self {
Error::DataTooBig => {
formatter.write_str("Received data larger than maximum configured limit")
}
Error::NotUndead => formatter.write_str("Useless attempt to reuse a functioning Foca"),
Error::SameIdentity => {
formatter.write_str("New identity is the same as the current one")
}
Error::NotConnected => formatter.write_str("BUG! Expected to be connected, but wasn't"),
Error::IncompleteProbeCycle => {
formatter.write_str("BUG! Probe cycle finished without running its full course")
}
Error::DataFromOurselves => formatter.write_str(concat!(
"Received data from something claiming to have ",
"an identity equal to our own"
)),
Error::IndirectForOurselves => formatter.write_str(concat!(
"Received message that was supposed to reach us only ",
"via indirect means"
)),
Error::MalformedPacket => formatter.write_str("Payload with more data than expected"),
Error::Encode(err) => err.fmt(formatter),
Error::Decode(err) => err.fmt(formatter),
Error::CustomBroadcast(err) => err.fmt(formatter),
Error::InvalidConfig => formatter.write_str("Invalid configuration"),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for Error {}
|