lib

Core libraries for Radroots
git clone https://radroots.dev/git/lib.git
Log | Files | Refs | README | LICENSE

error.rs (4382B)


      1 use thiserror::Error;
      2 
      3 #[derive(Debug, Error)]
      4 pub enum RuntimeConfigError {
      5     #[error("failed to load configuration from {path}: {source}")]
      6     Load {
      7         path: std::path::PathBuf,
      8         #[source]
      9         source: config::ConfigError,
     10     },
     11 }
     12 
     13 #[cfg(feature = "cli")]
     14 #[derive(Debug, Error)]
     15 pub enum RuntimeCliError {
     16     #[error(transparent)]
     17     Parse(#[from] clap::Error),
     18 
     19     #[error("configuration path is required; no implicit cwd-rooted default is used")]
     20     MissingConfigPath,
     21 }
     22 
     23 #[derive(Debug, Error)]
     24 pub enum RuntimeTracingError {
     25     #[error(transparent)]
     26     Log(#[from] radroots_log::Error),
     27 
     28     #[error(transparent)]
     29     Paths(#[from] radroots_runtime_paths::RadrootsRuntimePathsError),
     30 }
     31 
     32 #[derive(Debug, Error)]
     33 pub enum RuntimeProtectedFileError {
     34     #[error("failed to create directory {path}: {source}")]
     35     CreateDir {
     36         path: std::path::PathBuf,
     37         #[source]
     38         source: std::io::Error,
     39     },
     40     #[error("protected secret file io error at {path}: {source}")]
     41     Io {
     42         path: std::path::PathBuf,
     43         #[source]
     44         source: std::io::Error,
     45     },
     46     #[error("failed to seal protected secret file {path}: {message}")]
     47     Seal {
     48         path: std::path::PathBuf,
     49         message: String,
     50     },
     51     #[error("failed to decode protected secret file {path}: {message}")]
     52     Decode {
     53         path: std::path::PathBuf,
     54         message: String,
     55     },
     56     #[error("failed to open protected secret file {path}: {message}")]
     57     Open {
     58         path: std::path::PathBuf,
     59         message: String,
     60     },
     61     #[error("failed to update secret permissions for {path}: {message}")]
     62     Permissions {
     63         path: std::path::PathBuf,
     64         message: String,
     65     },
     66 }
     67 
     68 #[derive(Debug, Error)]
     69 pub enum RuntimeError {
     70     #[error(transparent)]
     71     Config(#[from] Box<RuntimeConfigError>),
     72 
     73     #[cfg(feature = "cli")]
     74     #[error(transparent)]
     75     Cli(#[from] RuntimeCliError),
     76 
     77     #[error(transparent)]
     78     Tracing(#[from] RuntimeTracingError),
     79 }
     80 
     81 impl From<RuntimeConfigError> for RuntimeError {
     82     fn from(value: RuntimeConfigError) -> Self {
     83         Self::Config(Box::new(value))
     84     }
     85 }
     86 
     87 #[cfg(test)]
     88 mod tests {
     89     use super::{RuntimeConfigError, RuntimeError, RuntimeProtectedFileError, RuntimeTracingError};
     90     use std::error::Error as _;
     91     use std::path::PathBuf;
     92 
     93     #[test]
     94     fn runtime_config_error_message_and_source_are_accessible() {
     95         let err = RuntimeConfigError::Load {
     96             path: PathBuf::from("config.toml"),
     97             source: config::ConfigError::Message("invalid config".to_string()),
     98         };
     99         let display = err.to_string();
    100         assert!(display.contains("config.toml"));
    101         assert!(display.contains("invalid config"));
    102         assert!(err.source().is_some());
    103     }
    104 
    105     #[test]
    106     fn runtime_error_conversions_include_config_and_tracing_variants() {
    107         let cfg = RuntimeConfigError::Load {
    108             path: PathBuf::from("runtime.toml"),
    109             source: config::ConfigError::Message("bad".to_string()),
    110         };
    111         let runtime_from_cfg: RuntimeError = cfg.into();
    112         assert!(runtime_from_cfg.to_string().contains("runtime.toml"));
    113         assert!(runtime_from_cfg.source().is_some());
    114 
    115         let tracing =
    116             RuntimeTracingError::from(radroots_log::Error::Msg("log-failure".to_string()));
    117         let runtime_from_tracing: RuntimeError = tracing.into();
    118         assert!(runtime_from_tracing.to_string().contains("log-failure"));
    119         assert!(runtime_from_tracing.source().is_none());
    120 
    121         let paths = RuntimeTracingError::from(
    122             radroots_runtime_paths::RadrootsRuntimePathsError::MissingHomeDir {
    123                 platform: radroots_runtime_paths::RadrootsPlatform::Linux,
    124             },
    125         );
    126         let runtime_from_paths: RuntimeError = paths.into();
    127         assert!(runtime_from_paths.to_string().contains("home directory"));
    128         assert!(runtime_from_paths.source().is_none());
    129     }
    130 
    131     #[test]
    132     fn protected_file_error_displays_path_and_message() {
    133         let err = RuntimeProtectedFileError::Open {
    134             path: PathBuf::from("identity.secret.json"),
    135             message: "missing wrapping key".to_string(),
    136         };
    137         let display = err.to_string();
    138         assert!(display.contains("identity.secret.json"));
    139         assert!(display.contains("missing wrapping key"));
    140     }
    141 }