Skip to content

Commit 0d1ebd8

Browse files
committed
Refactor errors
This commit is a start of refactoring of errors within the client. Remove From impl for Reqwest's Response type to Error as it isn't useful at this stage; a problem with a response is better handled inside of transport's async send() fn, where an Err could potentially be returned for a response deemed to be an error. For now, all HTTP status code responses from Elasticsearch return an Ok() result. Opened #28 to discuss.
1 parent 2fbdabc commit 0d1ebd8

File tree

4 files changed

+57
-21
lines changed

4 files changed

+57
-21
lines changed

elasticsearch/src/auth.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,13 @@ pub enum Credentials {
77
Basic(String, String),
88
/// An access_token to use for Bearer authentication
99
Bearer(String),
10-
/// Bytes of a PKCS#12 archive and password to use for PKI (Client Certificate) authentication
10+
/// Bytes of a DER-formatted PKCS#12 archive and password to use for
11+
/// PKI (Client Certificate) authentication.
12+
///
13+
/// The archive should contain a leaf certificate and its private key, as well any intermediate
14+
/// certificates that allow clients to build a chain to a trusted root. The chain certificates
15+
/// should be in order from the leaf certificate towards the root.
1116
Cert(Vec<u8>, String),
12-
/// An id an api_key to use for API key authentication
17+
/// An id and api_key to use for API key authentication
1318
ApiKey(String, String),
1419
}

elasticsearch/src/error.rs

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Error type based on error type from es-rs:
1+
/* Error type based on the error type from es-rs:
22
*
33
* Copyright 2015-2018 Ben Ashford
44
*
@@ -13,7 +13,6 @@
1313
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1414
* See the License for the specific language governing permissions and
1515
* limitations under the License.
16-
*
1716
*/
1817
use crate::http::transport::BuildError;
1918
use serde_json;
@@ -33,9 +32,6 @@ pub enum Error {
3332
/// A general error from this library
3433
Lib(String),
3534

36-
/// An error reported in a JSON response from Elasticsearch
37-
Server(String),
38-
3935
/// HTTP library error
4036
Http(reqwest::Error),
4137

@@ -76,20 +72,11 @@ impl From<BuildError> for Error {
7672
}
7773
}
7874

79-
impl<'a> From<&'a mut reqwest::Response> for Error {
80-
fn from(err: &'a mut reqwest::Response) -> Error {
81-
// TODO: figure out how to read the response body synchronously
82-
//let body = err.text().await?;
83-
Error::Server(format!("{} status code received", err.status()))
84-
}
85-
}
86-
8775
impl error::Error for Error {
8876
fn description(&self) -> &str {
8977
match *self {
9078
Error::Build(ref err) => err.description(),
9179
Error::Lib(ref err) => err,
92-
Error::Server(ref err) => err,
9380
Error::Http(ref err) => err.description(),
9481
Error::Io(ref err) => err.description(),
9582
Error::Json(ref err) => err.description(),
@@ -100,7 +87,6 @@ impl error::Error for Error {
10087
match *self {
10188
Error::Build(ref err) => Some(err as &dyn error::Error),
10289
Error::Lib(_) => None,
103-
Error::Server(_) => None,
10490
Error::Http(ref err) => Some(err as &dyn error::Error),
10591
Error::Io(ref err) => Some(err as &dyn error::Error),
10692
Error::Json(ref err) => Some(err as &dyn error::Error),
@@ -113,7 +99,6 @@ impl fmt::Display for Error {
11399
match *self {
114100
Error::Build(ref err) => fmt::Display::fmt(err, f),
115101
Error::Lib(ref s) => fmt::Display::fmt(s, f),
116-
Error::Server(ref s) => fmt::Display::fmt(s, f),
117102
Error::Http(ref err) => fmt::Display::fmt(err, f),
118103
Error::Io(ref err) => fmt::Display::fmt(err, f),
119104
Error::Json(ref err) => fmt::Display::fmt(err, f),

elasticsearch/src/http/transport.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,17 @@ impl Transport {
260260
}
261261
}
262262

263-
let response = request_builder.send().await?;
264-
Ok(Response::new(response))
263+
let response = request_builder.send().await;
264+
match response {
265+
Ok(r) => Ok(Response::new(r)),
266+
Err(e) => {
267+
if e.is_timeout() {
268+
Err(Error::Lib(format!("Request timed out to {:?}", e.url())))
269+
} else {
270+
Err(Error::Http(e))
271+
}
272+
}
273+
}
265274
}
266275
}
267276

@@ -434,9 +443,20 @@ impl ConnectionPool for CloudConnectionPool {
434443

435444
#[cfg(test)]
436445
pub mod tests {
437-
use crate::http::transport::CloudId;
446+
use crate::auth::Credentials;
447+
use crate::http::transport::{CloudId, TransportBuilder, SingleNodeConnectionPool};
438448
use url::Url;
439449

450+
#[test]
451+
fn invalid_cert_credentials() {
452+
let conn_pool = SingleNodeConnectionPool::default();
453+
let builder = TransportBuilder::new(conn_pool)
454+
.auth(Credentials::Cert(b"Nonsense".to_vec(), "".into()));
455+
456+
let res = builder.build();
457+
assert!(res.is_err());
458+
}
459+
440460
#[test]
441461
fn can_parse_cloud_id() {
442462
let base64 = base64::encode("cloud-endpoint.example$3dadf823f05388497ea684236d918a1a$3f26e1609cf54a0f80137a80de560da4");

elasticsearch/tests/error.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
pub mod common;
2+
use common::*;
3+
4+
use reqwest::StatusCode;
5+
use serde_json::{json, Value};
6+
use elasticsearch::ExplainParts;
7+
8+
/// Responses in the range 400-599 return Response body
9+
#[tokio::test]
10+
async fn bad_request_returns_response() -> Result<(), failure::Error> {
11+
let client = client::create_default();
12+
let response = client
13+
.explain(ExplainParts::IndexId("non_existent_index", "id"))
14+
.body(json!({}))
15+
.send()
16+
.await?;
17+
18+
assert_eq!(response.status_code(), StatusCode::BAD_REQUEST);
19+
20+
let error = response.read_body::<Value>().await?;
21+
assert_eq!(error["status"].as_i64(), Some(400));
22+
assert_eq!(error["error"]["type"].as_str(), Some("action_request_validation_exception"));
23+
assert_eq!(error["error"]["reason"].as_str(), Some("Validation Failed: 1: query is missing;"));
24+
25+
Ok(())
26+
}

0 commit comments

Comments
 (0)