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}