Skip to main content

couchbase_core/httpx/
error.rs

1/*
2 *
3 *  * Copyright (c) 2025 Couchbase, Inc.
4 *  *
5 *  * Licensed under the Apache License, Version 2.0 (the "License");
6 *  * you may not use this file except in compliance with the License.
7 *  * You may obtain a copy of the License at
8 *  *
9 *  *    http://www.apache.org/licenses/LICENSE-2.0
10 *  *
11 *  * Unless required by applicable law or agreed to in writing, software
12 *  * distributed under the License is distributed on an "AS IS" BASIS,
13 *  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  * See the License for the specific language governing permissions and
15 *  * limitations under the License.
16 *
17 */
18
19use crate::tracingcomponent::MetricsName;
20use std::error::Error as StdError;
21use std::fmt::{Display, Formatter};
22
23pub type Result<T> = std::result::Result<T, Error>;
24
25#[derive(Debug, Clone, PartialEq, Eq)]
26pub struct Error {
27    inner: Box<ErrorImpl>,
28}
29
30impl Display for Error {
31    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
32        write!(f, "{}", self.inner.kind)
33    }
34}
35
36impl StdError for Error {}
37
38impl Error {
39    pub(crate) fn new_message_error(msg: impl Into<String>) -> Self {
40        Self {
41            inner: Box::new(ErrorImpl {
42                kind: ErrorKind::Message(msg.into()),
43            }),
44        }
45    }
46
47    pub(crate) fn new_connect_error(msg: impl Into<String>) -> Self {
48        Self {
49            inner: Box::new(ErrorImpl {
50                kind: ErrorKind::Connect { msg: msg.into() },
51            }),
52        }
53    }
54
55    pub(crate) fn new_decoding_error(msg: impl Into<String>) -> Self {
56        Self {
57            inner: Box::new(ErrorImpl {
58                kind: ErrorKind::Decoding(msg.into()),
59            }),
60        }
61    }
62
63    pub(crate) fn new_request_error(msg: impl Into<String>) -> Self {
64        Self {
65            inner: Box::new(ErrorImpl {
66                kind: ErrorKind::SendRequest(msg.into()),
67            }),
68        }
69    }
70
71    pub fn is_connect_error(&self) -> bool {
72        matches!(self.inner.kind, ErrorKind::Connect { .. })
73    }
74
75    pub fn is_decoding_error(&self) -> bool {
76        matches!(self.inner.kind, ErrorKind::Decoding { .. })
77    }
78
79    pub fn kind(&self) -> &ErrorKind {
80        &self.inner.kind
81    }
82}
83
84#[derive(Debug, Clone, PartialEq, Eq)]
85pub struct ErrorImpl {
86    kind: ErrorKind,
87}
88
89#[derive(Clone, Debug, PartialEq, Eq)]
90#[non_exhaustive]
91pub enum ErrorKind {
92    #[non_exhaustive]
93    Connect {
94        msg: String,
95    },
96    Decoding(String),
97    Message(String),
98    SendRequest(String),
99}
100
101impl Display for ErrorKind {
102    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
103        match self {
104            Self::Connect { msg } => write!(f, "connect error {msg}"),
105            Self::Decoding(msg) => write!(f, "decoding error: {msg}"),
106            Self::Message(msg) => write!(f, "{msg}"),
107            Self::SendRequest(msg) => write!(f, "send request failed error: {msg}"),
108        }
109    }
110}
111
112impl MetricsName for Error {
113    fn metrics_name(&self) -> &'static str {
114        match self.kind() {
115            ErrorKind::Connect { .. } => "httpx.Connect",
116            ErrorKind::Decoding(_) => "httpx.Decoding",
117            ErrorKind::Message(_) => "httpx._OTHER",
118            ErrorKind::SendRequest(_) => "httpx.SendRequest",
119        }
120    }
121}