tibba_request/
lib.rs

1// Copyright 2025 Tree xie.
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 at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14use snafu::Snafu;
15use tibba_error::Error as BaseError;
16
17mod request;
18
19#[derive(Debug, Snafu)]
20pub enum Error {
21    #[snafu(display("{service} request fail, {message}"))]
22    Common { service: String, message: String },
23    #[snafu(display("{service} build http request fail, {source}"))]
24    Build {
25        service: String,
26        source: reqwest::Error,
27    },
28    #[snafu(display("{service} uri fail, {source}"))]
29    Uri {
30        service: String,
31        source: axum::http::uri::InvalidUri,
32    },
33    #[snafu(display("{service} http request fail, {path} {source}"))]
34    Request {
35        service: String,
36        path: String,
37        source: reqwest::Error,
38    },
39    #[snafu(display("{service} json fail, {source}"))]
40    Serde {
41        service: String,
42        source: serde_json::Error,
43    },
44}
45
46impl From<Error> for BaseError {
47    fn from(val: Error) -> Self {
48        // get service
49        let service = match &val {
50            Error::Common { service, .. } => service,
51            Error::Build { service, .. } => service,
52            Error::Uri { service, .. } => service,
53            Error::Request { service, .. } => service,
54            Error::Serde { service, .. } => service,
55        };
56
57        // match error
58        let err = match &val {
59            Error::Request { source, .. } => {
60                let status = source.status().map_or(500, |v| v.as_u16());
61                let is_network_exception = source.is_timeout() || source.is_connect();
62                BaseError::new(source)
63                    .with_status(status)
64                    .with_exception(is_network_exception)
65            }
66            Error::Common { message, .. } => BaseError::new(message),
67            Error::Build { source, .. } => BaseError::new(source),
68            Error::Uri { source, .. } => BaseError::new(source),
69            Error::Serde { source, .. } => BaseError::new(source),
70        };
71
72        err.with_sub_category(service).with_category("request")
73    }
74}
75
76pub use request::*;