aditjind_crate/
error.rs

1/*
2 * Licensed to Elasticsearch B.V. under one or more contributor
3 * license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright
5 * ownership. Elasticsearch B.V. licenses this file to you under
6 * the Apache License, Version 2.0 (the "License"); you may
7 * not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *	http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied.  See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19/* Error type based on the error type from es-rs:
20 *
21 * Copyright 2015-2018 Ben Ashford
22 *
23 * Licensed under the Apache License, Version 2.0 (the "License");
24 * you may not use this file except in compliance with the License.
25 * You may obtain a copy of the License at
26 *
27 *     http://www.apache.org/licenses/LICENSE-2.0
28 *
29 * Unless required by applicable law or agreed to in writing, software
30 * distributed under the License is distributed on an "AS IS" BASIS,
31 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
32 * See the License for the specific language governing permissions and
33 * limitations under the License.
34 */
35use crate::http::{transport::BuildError, StatusCode};
36use std::{error, fmt, io};
37
38/// An error with the client.
39///
40/// Errors that can occur include IO and parsing errors, as well as specific
41/// errors from Elasticsearch and internal errors from the client.
42#[derive(Debug)]
43pub struct Error {
44    kind: Kind,
45}
46
47#[derive(Debug)]
48enum Kind {
49    /// An error building the client
50    Build(BuildError),
51
52    /// A general error from this library
53    Lib(String),
54
55    /// HTTP library error
56    Http(reqwest::Error),
57
58    /// IO error
59    Io(io::Error),
60
61    /// JSON error
62    Json(serde_json::error::Error),
63}
64
65impl From<io::Error> for Error {
66    fn from(err: io::Error) -> Error {
67        Error {
68            kind: Kind::Io(err),
69        }
70    }
71}
72
73impl From<reqwest::Error> for Error {
74    fn from(err: reqwest::Error) -> Error {
75        Error {
76            kind: Kind::Http(err),
77        }
78    }
79}
80
81impl From<serde_json::error::Error> for Error {
82    fn from(err: serde_json::error::Error) -> Error {
83        Error {
84            kind: Kind::Json(err),
85        }
86    }
87}
88
89impl From<url::ParseError> for Error {
90    fn from(err: url::ParseError) -> Error {
91        Error {
92            kind: Kind::Lib(err.to_string()),
93        }
94    }
95}
96
97impl From<BuildError> for Error {
98    fn from(err: BuildError) -> Error {
99        Error {
100            kind: Kind::Build(err),
101        }
102    }
103}
104
105pub(crate) fn lib(err: impl Into<String>) -> Error {
106    Error {
107        kind: Kind::Lib(err.into()),
108    }
109}
110
111impl Error {
112    /// The status code, if the error was generated from a response
113    pub fn status_code(&self) -> Option<StatusCode> {
114        match &self.kind {
115            Kind::Http(err) => err.status(),
116            _ => None,
117        }
118    }
119
120    /// Returns true if the error is related to a timeout
121    pub fn is_timeout(&self) -> bool {
122        match &self.kind {
123            Kind::Http(err) => err.is_timeout(),
124            _ => false,
125        }
126    }
127
128    /// Returns true if the error is related to serialization or deserialization
129    pub fn is_json(&self) -> bool {
130        match &self.kind {
131            Kind::Json(_) => true,
132            _ => false,
133        }
134    }
135}
136
137impl error::Error for Error {
138    fn source(&self) -> Option<&(dyn error::Error + 'static)> {
139        match &self.kind {
140            Kind::Build(err) => Some(err),
141            Kind::Lib(_) => None,
142            Kind::Http(err) => Some(err),
143            Kind::Io(err) => Some(err),
144            Kind::Json(err) => Some(err),
145        }
146    }
147}
148
149impl fmt::Display for Error {
150    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
151        match &self.kind {
152            Kind::Build(err) => err.fmt(f),
153            Kind::Lib(err) => err.fmt(f),
154            Kind::Http(err) => err.fmt(f),
155            Kind::Io(err) => err.fmt(f),
156            Kind::Json(err) => err.fmt(f),
157        }
158    }
159}