Skip to content

Commit b620d22

Browse files
authored
Add Exception to model Elasticsearch exceptions (#118)
This commit adds an Exception struct that models exceptions returned by Elasticsearch in the event of an error. An exception() function is exposed on Response to deserialize the response body into Exception when the status code is in the 400-599 range. Consideration was made to exposing this on the Error struct, performing the deserialization inside `error_for_status_code`, but this introduces some awkwardness into the API: - `error_for_status_code` would ideally be async because the .json() call is async - .json() consumes the response, which would not be possible for `error_for_status_code_ref` which has a shared reference to Response. Consideration was made to combining `Error` and `Cause` into one type, since they both map to `ElasticsearchException` on the server side. It looks like certain properties are only ever exposed on the top level exception however, which is deserialized to `Error` e.g. root_cause, header and failed_shards (which is not currently mapped in Error). In light of this, decided to keep them separate for now. Additional details about an exception are collected in a map and exposed through additional_details function. Closes #112
1 parent f214808 commit b620d22

File tree

8 files changed

+536
-34
lines changed

8 files changed

+536
-34
lines changed

elasticsearch/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ url = "^2.1"
3131
serde = { version = "~1", features = ["derive"] }
3232
serde_json = "~1"
3333
serde_with = "~1"
34+
void = "1.0.2"
3435

3536
[dev-dependencies]
3637
chrono = { version = "^0.4", features = ["serde"] }

elasticsearch/examples/search_questions_answers/main.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ use std::env;
3131
use sysinfo::SystemExt;
3232
use url::Url;
3333
mod stack_overflow;
34-
use elasticsearch::http::response::Response;
3534
use stack_overflow::*;
3635
use textwrap::fill;
3736

elasticsearch/src/cert.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
* specific language governing permissions and limitations
1717
* under the License.
1818
*/
19+
//! Certificate components
1920
2021
use crate::error::Error;
2122
use std::{
@@ -229,8 +230,8 @@ impl Certificate {
229230
}
230231

231232
if certs.is_empty() {
232-
Err(Error::lib(
233-
"could not find PEM certificate in input data".to_string(),
233+
Err(crate::error::lib(
234+
"could not find PEM certificate in input data",
234235
))
235236
} else {
236237
Ok(Self(certs))

elasticsearch/src/error.rs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,13 @@
3232
* See the License for the specific language governing permissions and
3333
* limitations under the License.
3434
*/
35-
use crate::http::transport::BuildError;
35+
use crate::http::{transport::BuildError, StatusCode};
3636
use std::{error, fmt, io};
3737

38-
/// An error within the client.
38+
/// An error with the client.
3939
///
4040
/// Errors that can occur include IO and parsing errors, as well as specific
41-
/// errors from Elasticsearch and internal errors from this library
41+
/// errors from Elasticsearch and internal errors from the client.
4242
#[derive(Debug)]
4343
pub struct Error {
4444
kind: Kind,
@@ -102,10 +102,34 @@ impl From<BuildError> for Error {
102102
}
103103
}
104104

105+
pub(crate) fn lib(err: impl Into<String>) -> Error {
106+
Error {
107+
kind: Kind::Lib(err.into()),
108+
}
109+
}
110+
105111
impl Error {
106-
pub(crate) fn lib(err: impl Into<String>) -> Self {
107-
Error {
108-
kind: Kind::Lib(err.into()),
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,
109133
}
110134
}
111135
}

0 commit comments

Comments
 (0)