Skip to main content

ixa/
error.rs

1//! Provides [`IxaError`] and wraps other errors.
2use std::error::Error;
3use std::io;
4
5use thiserror::Error;
6
7#[derive(Error, Debug)]
8/// Provides [`IxaError`] and maps to other errors to
9/// convert to an [`IxaError`]
10pub enum IxaError {
11    #[error(transparent)]
12    IoError(#[from] io::Error),
13    #[error(transparent)]
14    JsonError(#[from] serde_json::Error),
15    #[error(transparent)]
16    CsvError(#[from] csv::Error),
17    #[error(transparent)]
18    Utf8Error(#[from] std::string::FromUtf8Error),
19    #[error(transparent)]
20    ParseIntError(#[from] std::num::ParseIntError),
21
22    #[error("duplicate property {name}")]
23    DuplicateProperty { name: String },
24    #[error("entry already exists")]
25    EntryAlreadyExists,
26    #[error("no global property: {name}")]
27    NoGlobalProperty { name: String },
28    #[error("property {name} is not set")]
29    PropertyNotSet { name: String },
30
31    #[error("illegal value for global property `{name}`: {source}")]
32    IllegalGlobalPropertyValue {
33        name: String,
34        source: Box<dyn Error + Send + Sync + 'static>,
35    },
36
37    #[error(
38        "the same property appears in both position {first_index} and {second_index} in the property list"
39    )]
40    DuplicatePropertyInPropertyList {
41        first_index: usize,
42        second_index: usize,
43    },
44
45    #[error("invalid key in pair: {pair}")]
46    InvalidLogLevelKey { pair: String },
47    #[error("invalid value in pair: {pair}")]
48    InvalidLogLevelValue { pair: String },
49    #[error("invalid log level: {level}")]
50    InvalidLogLevel { level: String },
51
52    #[error("invalid log level format: {log_level}")]
53    InvalidLogLevelFormat { log_level: String },
54
55    #[error("invalid runner config section `{section}`: {message}")]
56    InvalidRunnerConfig { section: String, message: String },
57
58    #[error("cannot make edge to self")]
59    CannotMakeEdgeToSelf,
60    #[error("invalid weight")]
61    InvalidWeight,
62    #[error("edge already exists")]
63    EdgeAlreadyExists,
64    #[error("can't sample from empty list")]
65    CannotSampleFromEmptyList,
66
67    #[error("initialization list is missing required properties")]
68    MissingRequiredInitializationProperties,
69}
70
71#[cfg(test)]
72mod tests {
73    use super::IxaError;
74
75    // `anyhow::Error` requires the wrapped error to be `Send + Sync + 'static`.
76    // These tests guard against a regression where a new variant (or a boxed
77    // source) loses those bounds and breaks interop with `anyhow`.
78
79    fn assert_send_sync<T: Send + Sync + 'static>() {}
80
81    #[test]
82    fn ixa_error_is_send_sync() {
83        assert_send_sync::<IxaError>();
84    }
85
86    #[test]
87    fn ixa_error_converts_to_anyhow() {
88        fn returns_anyhow() -> anyhow::Result<()> {
89            Err(IxaError::EntryAlreadyExists)?;
90            Ok(())
91        }
92        let err = returns_anyhow().unwrap_err();
93        assert!(err.downcast_ref::<IxaError>().is_some());
94    }
95}