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