avalanche_types/
errors.rs

1//! Custom error types used in avalanche-types.
2use std::{cell::RefCell, fmt, rc::Rc};
3
4use thiserror::Error;
5
6pub type Result<T> = std::result::Result<T, Error>;
7
8/// Backing errors for all consensus operations.
9#[derive(Clone, Debug, Error)]
10pub enum Error {
11    #[error("failed API (message: {message:?}, retryable: {retryable:?})")]
12    API { message: String, retryable: bool },
13    #[error("failed for other reasons (message: {message:?}, retryable: {retryable:?})")]
14    Other { message: String, retryable: bool },
15}
16
17impl Error {
18    /// Returns the error message in "String".
19    #[inline]
20    #[must_use]
21    pub fn message(&self) -> String {
22        match self {
23            Error::API { message, .. } | Error::Other { message, .. } => message.clone(),
24        }
25    }
26
27    /// Returns if the error is retryable.
28    #[inline]
29    #[must_use]
30    pub fn retryable(&self) -> bool {
31        match self {
32            Error::API { retryable, .. } | Error::Other { retryable, .. } => *retryable,
33        }
34    }
35
36    /// Returns true if the error message contains the substring.
37    #[inline]
38    #[must_use]
39    pub fn contains(&self, s: &str) -> bool {
40        self.message().contains(s)
41    }
42}
43
44#[derive(Debug)]
45pub struct Errors {
46    d: Rc<RefCell<Vec<Error>>>,
47}
48
49impl Errors {
50    pub fn new() -> Self {
51        Self {
52            d: Rc::new(RefCell::new(Vec::new())),
53        }
54    }
55
56    pub fn errored(&self) -> bool {
57        !self.d.borrow().is_empty()
58    }
59
60    pub fn add(&self, e: Error) {
61        self.d.borrow_mut().push(e);
62    }
63}
64
65impl Default for Errors {
66    fn default() -> Self {
67        Self::new()
68    }
69}
70
71/// ref. <https://doc.rust-lang.org/std/string/trait.ToString.html>
72/// ref. <https://doc.rust-lang.org/std/fmt/trait.Display.html>
73/// Use "Self.to_string()" to directly invoke this.
74impl fmt::Display for Errors {
75    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
76        let mut errs: Vec<String> = Vec::new();
77        for e in self.d.borrow().iter() {
78            errs.push(e.message());
79        }
80        write!(f, "{}", errs.join(", "))
81    }
82}