odoo_api/client/
error.rs

1use crate::jsonrpc::response::JsonRpcError;
2use thiserror::Error;
3
4/// An error during the response parsing phase
5///
6/// This error is used internally, and is typically parsed into either a
7/// [`ClosureError`] or a [`ReqwestError`].
8#[derive(Debug, Error)]
9pub enum ParseResponseError {
10    /// A parsing error from the serde_json library
11    ///
12    /// This might be raised if the returned JSON data is invalid, or couldn't
13    /// be parsed into the `XxxResponse` struct properly.
14    #[error(transparent)]
15    SerdeJsonError(#[from] serde_json::Error),
16
17    /// The Odoo API request was not successful
18    ///
19    /// See [`JsonRpcError`] for more details
20    #[error("JSON-RPC Error")]
21    JsonRpcError(#[from] JsonRpcError),
22}
23
24pub type ParseResponseResult<T> = std::result::Result<T, ParseResponseError>;
25
26#[derive(Debug, Error)]
27pub enum AuthenticationError {
28    /// A parsing error from the serde_json library
29    ///
30    /// This might be raised if the returned JSON data is invalid, or couldn't
31    /// be parsed into the `XxxResponse` struct properly.
32    #[error(transparent)]
33    SerdeJsonError(#[from] serde_json::Error),
34
35    /// An error occured while parsing the `uid` field from the authenticate
36    /// response
37    #[error("UID Parser Error")]
38    UidParseError(String),
39}
40
41pub type AuthenticationResult<T> = std::result::Result<T, AuthenticationError>;
42
43/// An error sending a closure-based [`OdooRequest`](crate::client::OdooRequest)
44///
45///
46#[derive(Debug, Error)]
47pub enum ClosureError {
48    /// An error occured inside the custom closure
49    ///
50    /// We include a blanket from Box\<dyn Error\> here because the concrete error
51    /// type cannot be known here (i.e., only the crate *consumer* will know the
52    /// type). This allows `fallible()?` to correctly return the ClosureError type
53    #[error(transparent)]
54    ClosureError(#[from] Box<dyn std::error::Error>),
55
56    /// A parsing error from the serde_json library
57    ///
58    /// This might be raised if the returned JSON data is invalid, or couldn't
59    /// be parsed into the `XxxResponse` struct properly.
60    #[error(transparent)]
61    SerdeJsonError(#[from] serde_json::Error),
62
63    /// The Odoo API request was not successful
64    ///
65    /// See [`JsonRpcError`] for more details
66    #[error("JSON-RPC Error")]
67    JsonRpcError(#[from] JsonRpcError),
68}
69
70// This is nicer than having a `ParseError` variant on the `ClosureError` struct
71// (which would duplicate these fields anyways)
72impl From<ParseResponseError> for ClosureError {
73    fn from(value: ParseResponseError) -> Self {
74        match value {
75            ParseResponseError::JsonRpcError(err) => Self::JsonRpcError(err),
76            ParseResponseError::SerdeJsonError(err) => Self::SerdeJsonError(err),
77        }
78    }
79}
80
81pub type ClosureResult<T> = std::result::Result<T, ClosureError>;
82
83/// An error during the `authenticate()` call
84#[derive(Debug, Error)]
85pub enum ClosureAuthError {
86    /// An error occured during the serialization, sending, receiving, or deserialization
87    /// of the request
88    #[error(transparent)]
89    ClosureError(#[from] ClosureError),
90
91    /// An error occured while parsing the `uid` field from the authenticate
92    /// response
93    #[error("UID Parser Error")]
94    UidParseError(String),
95}
96
97// As with `From<ParseResponseError>`, we'd like to avoid having duplicate error fields
98impl From<AuthenticationError> for ClosureAuthError {
99    fn from(value: AuthenticationError) -> Self {
100        match value {
101            AuthenticationError::SerdeJsonError(err) => {
102                Self::ClosureError(ClosureError::SerdeJsonError(err))
103            }
104            AuthenticationError::UidParseError(err) => Self::UidParseError(err),
105        }
106    }
107}
108
109pub type ClosureAuthResult<T> = std::result::Result<T, ClosureAuthError>;
110
111#[derive(Debug, Error)]
112pub enum ReqwestError {
113    /// An error from the [`reqwest`] library
114    ///
115    /// See [`reqwest::Error`] for more information.
116    #[cfg(any(feature = "async", feature = "blocking"))]
117    #[error(transparent)]
118    ReqwestError(#[from] reqwest::Error),
119
120    /// A parsing error from the serde_json library
121    ///
122    /// This might be raised if the returned JSON data is invalid, or couldn't
123    /// be parsed into the `XxxResponse` struct properly.
124    #[error(transparent)]
125    SerdeJsonError(#[from] serde_json::Error),
126
127    /// The Odoo API request was not successful
128    ///
129    /// See [`JsonRpcError`] for more details
130    #[error("JSON-RPC Error")]
131    JsonRpcError(#[from] JsonRpcError),
132}
133
134impl From<ParseResponseError> for ReqwestError {
135    fn from(value: ParseResponseError) -> Self {
136        match value {
137            ParseResponseError::JsonRpcError(err) => Self::JsonRpcError(err),
138            ParseResponseError::SerdeJsonError(err) => Self::SerdeJsonError(err),
139        }
140    }
141}
142
143pub type ReqwestResult<T> = std::result::Result<T, ReqwestError>;
144
145#[derive(Debug, Error)]
146pub enum ReqwestAuthError {
147    #[error(transparent)]
148    ReqwestError(#[from] ReqwestError),
149
150    /// An error occured while parsing the `uid` field from the authenticate
151    /// response
152    #[error("UID Parser Error")]
153    UidParseError(String),
154}
155
156// As with `From<ParseResponseError>`, we'd like to avoid having duplicate error fields
157impl From<AuthenticationError> for ReqwestAuthError {
158    fn from(value: AuthenticationError) -> Self {
159        match value {
160            AuthenticationError::SerdeJsonError(err) => {
161                Self::ReqwestError(ReqwestError::SerdeJsonError(err))
162            }
163            AuthenticationError::UidParseError(err) => Self::UidParseError(err),
164        }
165    }
166}
167
168pub type ReqwestAuthResult<T> = std::result::Result<T, ReqwestAuthError>;
169
170#[derive(Debug, Error)]
171pub enum Error {
172    /// An error occured inside the custom closure
173    ///
174    /// We include a blanket from Box\<dyn Error\> here because the concrete error
175    /// type cannot be known here (i.e., only the crate *consumer* will know the
176    /// type). This allows `fallible()?` to correctly return the ClosureError type
177    #[error(transparent)]
178    ClosureError(#[from] Box<dyn std::error::Error>),
179
180    /// An error from the [`reqwest`] library
181    ///
182    /// See [`reqwest::Error`] for more information.
183    #[cfg(any(feature = "async", feature = "blocking"))]
184    #[error(transparent)]
185    ReqwestError(#[from] reqwest::Error),
186
187    /// A parsing error from the serde_json library
188    ///
189    /// This might be raised if the returned JSON data is invalid, or couldn't
190    /// be parsed into the `XxxResponse` struct properly.
191    #[error(transparent)]
192    SerdeJsonError(#[from] serde_json::Error),
193
194    /// The Odoo API request was not successful
195    ///
196    /// See [`JsonRpcError`] for more details
197    #[error("JSON-RPC Error")]
198    JsonRpcError(#[from] JsonRpcError),
199
200    /// An error occured while parsing the `uid` field from the authenticate
201    /// response
202    #[error("UID Parser Error")]
203    UidParseError(String),
204}
205
206// This is nicer than having a `ParseError` variant on the `ClosureError` struct
207// (which would duplicate these fields anyways)
208impl From<ParseResponseError> for Error {
209    fn from(value: ParseResponseError) -> Self {
210        match value {
211            ParseResponseError::JsonRpcError(err) => Self::JsonRpcError(err),
212            ParseResponseError::SerdeJsonError(err) => Self::SerdeJsonError(err),
213        }
214    }
215}
216
217// As with `From<ParseResponseError>`, we'd like to avoid having duplicate error fields
218impl From<AuthenticationError> for Error {
219    fn from(value: AuthenticationError) -> Self {
220        match value {
221            AuthenticationError::SerdeJsonError(err) => Self::SerdeJsonError(err),
222            AuthenticationError::UidParseError(err) => Self::UidParseError(err),
223        }
224    }
225}
226
227impl From<ClosureError> for Error {
228    fn from(value: ClosureError) -> Self {
229        match value {
230            ClosureError::ClosureError(err) => Self::ClosureError(err),
231            ClosureError::JsonRpcError(err) => Self::JsonRpcError(err),
232            ClosureError::SerdeJsonError(err) => Self::SerdeJsonError(err),
233        }
234    }
235}
236
237impl From<ClosureAuthError> for Error {
238    fn from(value: ClosureAuthError) -> Self {
239        match value {
240            ClosureAuthError::ClosureError(err) => err.into(),
241            ClosureAuthError::UidParseError(err) => Self::UidParseError(err),
242        }
243    }
244}
245
246impl From<ReqwestError> for Error {
247    fn from(value: ReqwestError) -> Self {
248        match value {
249            ReqwestError::ReqwestError(err) => Self::ReqwestError(err),
250            ReqwestError::JsonRpcError(err) => Self::JsonRpcError(err),
251            ReqwestError::SerdeJsonError(err) => Self::SerdeJsonError(err),
252        }
253    }
254}
255
256impl From<ReqwestAuthError> for Error {
257    fn from(value: ReqwestAuthError) -> Self {
258        match value {
259            ReqwestAuthError::ReqwestError(err) => err.into(),
260            ReqwestAuthError::UidParseError(err) => Self::UidParseError(err),
261        }
262    }
263}
264
265pub type Result<T> = std::result::Result<T, Error>;