pubchem/
error.rs

1//! Ubiquitous types for error management.
2
3use std::io::Error as IoError;
4use std::num::ParseFloatError;
5use std::num::ParseIntError;
6
7use quick_xml::Error as XmlError;
8use thiserror::Error;
9use ureq::Error as UreqError;
10
11#[derive(Debug, Error, Clone, PartialEq, Eq)]
12/// An error returned by the Power User Gateway REST API.
13pub enum ApiError {
14    #[error("bad request: {0}")]
15    /// Request is improperly formed.
16    BadRequest(String),
17    #[error("not found: {0}")]
18    /// The input record was not found.
19    NotFound(String),
20    #[error("not allowed: {0}")]
21    /// Request not allowed.
22    NotAllowed(String),
23    #[error("timeout: {0}")]
24    /// The request timed out, from server overload or too broad a request.
25    Timeout(String),
26    #[error("server busy: {0}")]
27    /// Too many requests or server is busy, retry later.
28    ServerBusy(String),
29    #[error("unimplemented!(): {0}")]
30    /// The requested operation has not (yet) been implemented by the server.
31    Unimplemented(String),
32    #[error("server error: {0}")]
33    /// Some problem on the server side (such as a database server down).
34    ServerError(String),
35    #[error("unknown error: {0}")]
36    /// An unknown error occurred
37    Unknown(String),
38}
39
40impl From<crate::model::rest::Fault> for ApiError {
41    fn from(fault: crate::model::rest::Fault) -> Self {
42        match fault.code.as_str() {
43            "PUGREST.BadRequest" => ApiError::BadRequest(fault.message),
44            "PUGREST.NotFound" => ApiError::NotFound(fault.message),
45            "PUGREST.NotAllowed" => ApiError::NotAllowed(fault.message),
46            "PUGREST.Timeout" => ApiError::Timeout(fault.message),
47            "PUGREST.ServerBusy" => ApiError::ServerBusy(fault.message),
48            "PUGREST.Unimplemented" => ApiError::Unimplemented(fault.message),
49            "PUGREST.ServerError" => ApiError::ServerError(fault.message),
50            _ => ApiError::Unknown(fault.message),
51        }
52    }
53}
54
55// ---------------------------------------------------------------------------
56
57#[derive(Debug, Error, Clone, PartialEq, Eq)]
58/// An error raised by a `FromStr` implementor.
59pub enum ParseError {
60    #[error(transparent)]
61    Int(#[from] ParseIntError),
62    #[error(transparent)]
63    Float(#[from] ParseFloatError),
64}
65
66// ---------------------------------------------------------------------------
67
68#[derive(Debug, Error)]
69/// The main error type for the [`pubchem`] crate.
70///
71/// [`pubchem`]: ../index.html
72pub enum Error {
73    #[error(transparent)]
74    /// The PubChem API responded with an error.
75    Api(#[from] ApiError),
76    #[error(transparent)]
77    /// The HTTP client encountered an error.
78    Request(#[from] UreqError),
79    #[error(transparent)]
80    /// The XML parser encountered an error.
81    ///
82    /// *Any error from the underlying reader will be wrapped in the
83    /// [`XmlError::Io`] variant.*
84    ///
85    /// [`XmlError::Io`]: https://docs.rs/quick-xml/latest/quick_xml/enum.Error.html#variant.Io
86    Xml(#[from] XmlError),
87    #[error(transparent)]
88    /// A parser returned an error.
89    Parse(#[from] ParseError),
90}
91
92impl From<IoError> for Error {
93    fn from(e: IoError) -> Self {
94        Self::from(XmlError::Io(e))
95    }
96}
97
98impl From<ParseIntError> for Error {
99    fn from(e: ParseIntError) -> Self {
100        Self::Parse(ParseError::Int(e))
101    }
102}
103
104impl From<ParseFloatError> for Error {
105    fn from(e: ParseFloatError) -> Self {
106        Self::Parse(ParseError::Float(e))
107    }
108}
109
110/// The main result type for the [`pubchem`] crate.
111///
112/// [`pubchem`]: ../index.html
113pub type Result<T> = std::result::Result<T, Error>;