infisical_api/
error.rs

1use onionsalt::crypto::NaClError;
2use std::error::Error as StdError;
3use std::fmt;
4
5use crate::api::models::ErrorResponse;
6
7/// A `Result` alias where the `Err` case is `infisical_api::Error`.
8pub type Result<T> = std::result::Result<T, Error>;
9
10/// The Errors that may occur while utilizing infisical_api functionality
11pub struct Error {
12    inner: Box<Inner>,
13}
14
15pub(crate) type BoxError = Box<dyn StdError + Send + Sync>;
16
17struct Inner {
18    kind: Kind,
19    source: Option<BoxError>,
20}
21
22impl Error {
23    pub(crate) fn new<E>(kind: Kind, source: Option<E>) -> Error
24    where
25        E: Into<BoxError>,
26    {
27        Error {
28            inner: Box::new(Inner {
29                kind,
30                source: source.map(Into::into),
31            }),
32        }
33    }
34}
35
36impl fmt::Debug for Error {
37    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38        let mut builder = f.debug_struct("infisical_rs::Error");
39
40        builder.field("kind", &self.inner.kind);
41
42        if let Some(ref source) = self.inner.source {
43            builder.field("source", source);
44        }
45
46        builder.finish()
47    }
48}
49
50impl fmt::Display for Error {
51    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
52        match self.inner.kind {
53            Kind::Encrypt => f.write_str("Encryption error")?,
54            Kind::Decrypt => f.write_str("Decryption error")?,
55            Kind::Reqwest => f.write_str("Reqwest error")?,
56            Kind::UTF8 => f.write_str("UTF8 error")?,
57            Kind::NaCl => f.write_str("NaCl error")?,
58            Kind::Builder => f.write_str("Builder error")?,
59            Kind::API => f.write_str("Infisical API error")?,
60        };
61
62        if let Some(e) = &self.inner.source {
63            write!(f, ": {}", e);
64        }
65
66        Ok(())
67    }
68}
69
70impl StdError for Error {
71    fn source(&self) -> Option<&(dyn StdError + 'static)> {
72        self.inner.source.as_ref().map(|e| &**e as _)
73    }
74}
75
76impl StdError for ErrorResponse {
77    fn source(&self) -> Option<&(dyn StdError + 'static)> {
78        None
79    }
80}
81
82impl fmt::Display for ErrorResponse {
83    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
84        f.write_str("Infisical API error");
85
86        Ok(())
87    }
88}
89
90#[derive(Debug)]
91pub(crate) enum Kind {
92    Encrypt,
93    Decrypt,
94    Reqwest,
95    UTF8,
96    NaCl,
97    Builder,
98    API,
99}
100
101impl From<aes_gcm::Error> for Error {
102    fn from(_err: aes_gcm::Error) -> Error {
103        Error::new(Kind::Decrypt, None::<Error>)
104    }
105}
106
107impl From<NaClError> for Error {
108    fn from(err: NaClError) -> Error {
109        nacl(err)
110    }
111}
112
113// This just swallows any detail that InvalidLength would provide
114// TODO: Find a better way to handle
115impl From<aes_gcm::aes::cipher::InvalidLength> for Error {
116    fn from(err: aes_gcm::aes::cipher::InvalidLength) -> Error {
117        Error::new(Kind::Decrypt, None::<Error>)
118    }
119}
120
121impl From<reqwest::Error> for Error {
122    fn from(err: reqwest::Error) -> Error {
123        reqwest(err)
124    }
125}
126
127impl From<ErrorResponse> for Error {
128    fn from(err: ErrorResponse) -> Error {
129        api(err)
130    }
131}
132
133pub(crate) fn encrypt<E: Into<BoxError>>(e: E) -> Error {
134    Error::new(Kind::Encrypt, Some(e))
135}
136
137pub(crate) fn decrypt<E: Into<BoxError>>(e: E) -> Error {
138    Error::new(Kind::Decrypt, Some(e))
139}
140
141pub(crate) fn reqwest<E: Into<BoxError>>(e: E) -> Error {
142    Error::new(Kind::Reqwest, Some(e))
143}
144
145pub(crate) fn utf8<E: Into<BoxError>>(e: E) -> Error {
146    Error::new(Kind::UTF8, Some(e))
147}
148
149pub(crate) fn api<E: Into<BoxError>>(e: E) -> Error {
150    Error::new(Kind::API, Some(e))
151}
152
153pub(crate) fn nacl(e: NaClError) -> Error {
154    match e {
155        NaClError::IOError(io_error) => Error::new(Kind::NaCl, Some(io_error)),
156        NaClError::WrongKey => Error::new(Kind::NaCl, None::<Error>),
157        NaClError::RecvError(recv_error) => Error::new(Kind::NaCl, Some(recv_error)),
158        NaClError::AuthFailed => Error::new(Kind::NaCl, None::<Error>),
159    }
160}
161
162pub(crate) fn builder<E: Into<BoxError>>(e: E) -> Error {
163    Error::new(Kind::Builder, Some(e))
164}