nimbus/
error.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
4 * */
5
6//! Not complete yet
7//! This is where the error definitions can go
8//! TODO: Implement proper error handling, this would include defining the error enum,
9//! impl std::error::Error using `thiserror` and ensuring all errors are handled appropriately
10
11// reexport logging helpers.
12pub use error_support::{debug, error, info, trace, warn};
13
14#[cfg(feature = "stateful")]
15use firefox_versioning::error::VersionParsingError;
16use std::num::{ParseIntError, TryFromIntError};
17
18#[derive(Debug, thiserror::Error)]
19pub enum NimbusError {
20    #[error("Invalid persisted data")]
21    InvalidPersistedData,
22    #[cfg(feature = "stateful")]
23    #[error("Rkv error: {0}")]
24    RkvError(#[from] rkv::StoreError),
25    #[error("IO error: {0}")]
26    IOError(#[from] std::io::Error),
27    #[error("JSON Error: {0} — {1}")]
28    JSONError(String, String),
29    #[error("EvaluationError: {0}")]
30    EvaluationError(String),
31    #[error("Invalid Expression - didn't evaluate to a bool")]
32    InvalidExpression,
33    #[error("InvalidFractionError: Should be between 0 and 1")]
34    InvalidFraction,
35    #[error("TryInto error: {0}")]
36    TryFromSliceError(#[from] std::array::TryFromSliceError),
37    #[error("Empty ratios!")]
38    EmptyRatiosError,
39    #[error("Attempt to access an element that is out of bounds")]
40    OutOfBoundsError,
41    #[error("Error parsing URL: {0}")]
42    UrlParsingError(#[from] url::ParseError),
43    #[error("UUID parsing error: {0}")]
44    UuidError(#[from] uuid::Error),
45    #[error("Invalid experiment data received")]
46    InvalidExperimentFormat,
47    #[error("Invalid path: {0}")]
48    InvalidPath(String),
49    #[error("Internal error: {0}")]
50    InternalError(&'static str),
51    #[error("The experiment {0} does not exist")]
52    NoSuchExperiment(String),
53    #[error("The branch {0} does not exist for the experiment {1}")]
54    NoSuchBranch(String, String),
55    #[error("Initialization of the database is not yet complete")]
56    DatabaseNotReady,
57    #[error("Error parsing a string into a version {0}")]
58    VersionParsingError(String),
59    #[cfg(feature = "stateful")]
60    #[error("Behavior error: {0}")]
61    BehaviorError(#[from] BehaviorError),
62    #[error("TryFromIntError: {0}")]
63    TryFromIntError(#[from] TryFromIntError),
64    #[error("ParseIntError: {0}")]
65    ParseIntError(#[from] ParseIntError),
66    #[error("Transform parameter error: {0}")]
67    TransformParameterError(String),
68    #[cfg(feature = "stateful")]
69    #[error("Error with Remote Settings client: {0}")]
70    ClientError(#[from] remote_settings::RemoteSettingsError),
71    #[cfg(not(feature = "stateful"))]
72    #[error("Error in Cirrus: {0}")]
73    CirrusError(#[from] CirrusClientError),
74    #[error("UniFFI callback error: {0}")]
75    UniFFICallbackError(#[from] uniffi::UnexpectedUniFFICallbackError),
76    #[cfg(feature = "stateful")]
77    #[error("Regex error: {0}")]
78    RegexError(#[from] regex::Error),
79}
80
81#[cfg(feature = "stateful")]
82#[derive(Debug, thiserror::Error)]
83pub enum BehaviorError {
84    #[error("Invalid state: {0}")]
85    InvalidState(String),
86    #[error("Invalid duration: {0}")]
87    InvalidDuration(String),
88    #[error("IntervalParseError: {0} is not a valid Interval")]
89    IntervalParseError(String),
90    #[error("The event store is not available on the targeting attributes")]
91    MissingEventStore,
92    #[error("The recorded context is not available on the nimbus client")]
93    MissingRecordedContext,
94    #[error("EventQueryTypeParseError: {0} is not a valid EventQueryType")]
95    EventQueryTypeParseError(String),
96    #[error(r#"EventQueryParseError: "{0}" is not a valid EventQuery"#)]
97    EventQueryParseError(String),
98    #[error(r#"TypeError: "{0}" is not of type {1}"#)]
99    TypeError(String, String),
100}
101
102#[cfg(not(feature = "stateful"))]
103#[derive(Debug, thiserror::Error)]
104pub enum CirrusClientError {
105    #[error("Request missing parameter: {0}")]
106    RequestMissingParameter(String),
107}
108
109#[cfg(test)]
110impl From<serde_json::Error> for NimbusError {
111    fn from(error: serde_json::Error) -> Self {
112        NimbusError::JSONError("test".into(), error.to_string())
113    }
114}
115
116impl<'a> From<jexl_eval::error::EvaluationError<'a>> for NimbusError {
117    fn from(eval_error: jexl_eval::error::EvaluationError<'a>) -> Self {
118        NimbusError::EvaluationError(eval_error.to_string())
119    }
120}
121
122#[cfg(feature = "stateful")]
123impl From<VersionParsingError> for NimbusError {
124    fn from(eval_error: VersionParsingError) -> Self {
125        NimbusError::VersionParsingError(eval_error.to_string())
126    }
127}
128
129pub type Result<T, E = NimbusError> = std::result::Result<T, E>;