op_config/providers/
error.rs

1//! error handling and solc error codes
2use figment::providers::{Format, Toml};
3use std::{collections::HashSet, error::Error, fmt};
4
5/// The message shown upon panic if the config could not be extracted from the figment
6pub(crate) const FAILED_TO_EXTRACT_CONFIG_PANIC_MSG: &str = "failed to extract config:";
7
8/// Represents a failed attempt to extract `Config` from a `Figment`
9#[derive(Clone, Debug, PartialEq)]
10pub struct ExtractConfigError {
11    /// error thrown when extracting the `Config`
12    pub(crate) error: figment::Error,
13}
14
15impl ExtractConfigError {
16    /// Wraps the figment error
17    pub fn new(error: figment::Error) -> Self {
18        Self { error }
19    }
20}
21
22impl fmt::Display for ExtractConfigError {
23    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24        let mut unique_errors = Vec::with_capacity(self.error.count());
25        let mut unique = HashSet::with_capacity(self.error.count());
26        for err in self.error.clone().into_iter() {
27            let err = if err
28                .metadata
29                .as_ref()
30                .map(|meta| meta.name.contains(Toml::NAME))
31                .unwrap_or_default()
32            {
33                OpStackConfigError::Toml(err)
34            } else {
35                OpStackConfigError::Other(err)
36            };
37
38            if unique.insert(err.to_string()) {
39                unique_errors.push(err);
40            }
41        }
42        writeln!(f, "{FAILED_TO_EXTRACT_CONFIG_PANIC_MSG}")?;
43        for err in unique_errors {
44            writeln!(f, "{err}")?;
45        }
46        Ok(())
47    }
48}
49
50impl Error for ExtractConfigError {
51    fn source(&self) -> Option<&(dyn Error + 'static)> {
52        Error::source(&self.error)
53    }
54}
55
56/// Represents an error that can occur when constructing the `Config`
57#[derive(Debug, Clone, PartialEq)]
58pub enum OpStackConfigError {
59    /// An error thrown during toml parsing
60    Toml(figment::Error),
61    /// Any other error thrown when constructing the config's figment
62    Other(figment::Error),
63}
64
65impl fmt::Display for OpStackConfigError {
66    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67        let fmt_err = |err: &figment::Error, f: &mut fmt::Formatter<'_>| {
68            write!(f, "{err}")?;
69            if !err.path.is_empty() {
70                // the path will contain the setting value like `["etherscan_api_key"]`
71                write!(f, " for setting `{}`", err.path.join("."))?;
72            }
73            Ok(())
74        };
75
76        match self {
77            OpStackConfigError::Toml(err) => {
78                f.write_str("stack.toml error: ")?;
79                fmt_err(err, f)
80            }
81            OpStackConfigError::Other(err) => {
82                f.write_str("op stack config error: ")?;
83                fmt_err(err, f)
84            }
85        }
86    }
87}
88
89impl Error for OpStackConfigError {
90    fn source(&self) -> Option<&(dyn Error + 'static)> {
91        match self {
92            OpStackConfigError::Other(error) | OpStackConfigError::Toml(error) => {
93                Error::source(error)
94            }
95        }
96    }
97}