orb_billing/
error.rs

1// Copyright Materialize, Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License in the LICENSE file at the
6// root of this repository, or online at
7//
8//     http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16use std::fmt;
17
18use reqwest::StatusCode;
19
20/// An error returned by a [`Client`].
21///
22/// [`Client`]: crate::Client
23#[derive(Debug)]
24pub enum Error {
25    /// An error in the underlying transport.
26    Transport(reqwest::Error),
27    /// An error returned by the API.
28    Api(ApiError),
29    /// The API returned an unexpected response.
30    UnexpectedResponse {
31        /// Details about the nature of the unexpected response.
32        detail: String,
33    },
34}
35
36impl fmt::Display for Error {
37    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
38        match self {
39            Error::Transport(e) => write!(f, "orb error: transport: {e}"),
40            Error::Api(e) => write!(f, "orb error: api: {e}"),
41            Error::UnexpectedResponse { detail } => {
42                write!(f, "orb error: unexpected response: {detail}")
43            }
44        }
45    }
46}
47
48impl std::error::Error for Error {}
49
50/// An error returned by the Orb API.
51///
52/// For details, see: <https://docs.withorb.com/docs/orb-docs/error-responses>
53#[derive(Debug, Clone)]
54pub struct ApiError {
55    /// The HTTP status code.
56    pub status_code: StatusCode,
57    /// A brief description of the error message.
58    pub title: String,
59    /// A human-readable description providing more insight into the error.
60    pub detail: Option<String>,
61    /// Errors that occurred while validating the request.
62    pub validation_errors: Vec<String>,
63}
64
65impl fmt::Display for ApiError {
66    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
67        write!(f, "{}", self.title)?;
68        if let Some(detail) = &self.detail {
69            write!(f, ": {detail}")?;
70        }
71        write!(f, " (status {})", self.status_code)?;
72        write!(
73            f,
74            "; validation errors: {}",
75            self.validation_errors.join(",")
76        )
77    }
78}
79
80impl std::error::Error for ApiError {}
81
82impl From<reqwest::Error> for Error {
83    fn from(e: reqwest::Error) -> Error {
84        Error::Transport(e)
85    }
86}
87
88impl From<ApiError> for Error {
89    fn from(e: ApiError) -> Error {
90        Error::Api(e)
91    }
92}