//! Test network errors use std::{fmt, time}; use failure; use hbbft::messaging::DistAlgorithm; use super::NetMessage; /// Network crank error. /// /// Errors resulting from processing a single message ("cranking"). pub enum CrankError where D: DistAlgorithm, { /// The algorithm run by the node produced a `DistAlgorithm::Error` while processing input. AlgorithmError { /// Network message that triggered the error. msg: NetMessage, err: D::Error, }, /// A node unexpectly disappeared from the list of nodes. Note that this is likely a bug in /// the network framework code. NodeDisappeared(D::NodeId), /// The configured maximum number of cranks has been reached or exceeded. CrankLimitExceeded(usize), /// The configured maximum number of messages has been reached or exceeded. MessageLimitExceeded(usize), /// The execution time limit has been reached or exceeded. TimeLimitHit(time::Duration), } // Note: Deriving [Debug](std::fmt::Debug), [Fail](failure::Fail) and through that, // [Debug](std::fmt::Debug) automatically does not work due to the wrongly required trait // bound of `D: DistAlgorithm` implementing the respective Trait. For this reason, these // three traits are implemented manually. // // More details at // // * // * impl fmt::Display for CrankError where D: DistAlgorithm, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { CrankError::AlgorithmError { msg, err } => write!( f, "The algorithm could not process network message {:?}. Error: {:?}", msg, err ), CrankError::NodeDisappeared(id) => write!( f, "Node {:?} disappeared or never existed, while it still had incoming messages.", id ), CrankError::CrankLimitExceeded(max) => { write!(f, "Maximum number of cranks exceeded: {}", max) } CrankError::MessageLimitExceeded(max) => { write!(f, "Maximum number of messages exceeded: {}", max) } CrankError::TimeLimitHit(lim) => { write!(f, "Time limit of {} seconds exceeded.", lim.as_secs()) } } } } impl fmt::Debug for CrankError where D: DistAlgorithm, { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { CrankError::AlgorithmError { msg, err } => f .debug_struct("AlgorithmError") .field("msg", msg) .field("err", err) .finish(), CrankError::NodeDisappeared(id) => f.debug_tuple("NodeDisappeared").field(id).finish(), CrankError::CrankLimitExceeded(max) => { f.debug_tuple("CrankLimitExceeded").field(max).finish() } CrankError::MessageLimitExceeded(max) => { f.debug_tuple("MessageLimitExceeded").field(max).finish() } CrankError::TimeLimitHit(lim) => f.debug_tuple("TimeLimitHit").field(lim).finish(), } } } impl failure::Fail for CrankError where D: DistAlgorithm + 'static, { fn cause(&self) -> Option<&failure::Fail> { match self { CrankError::AlgorithmError { err, .. } => Some(err), _ => None, } } }