summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFerris Tseng <ferristseng@fastmail.fm>2021-02-22 22:56:04 -0500
committerFerris Tseng <ferristseng@fastmail.fm>2021-02-22 22:56:04 -0500
commit4ede307efb87bad2627190665279123e588a3494 (patch)
tree22795c2bc10d96e34a126863ef01e6b86ea9a5a3
parent89519b4c5ce4839a362ab9ec9c6359f3c6aa844b (diff)
centralize errors in prelude as much as possible
-rw-r--r--ipfs-api-backend-actix/Cargo.toml4
-rw-r--r--ipfs-api-backend-actix/src/backend.rs23
-rw-r--r--ipfs-api-backend-actix/src/error.rs13
-rw-r--r--ipfs-api-backend-hyper/Cargo.toml4
-rw-r--r--ipfs-api-backend-hyper/src/backend.rs24
-rw-r--r--ipfs-api-backend-hyper/src/error.rs13
-rw-r--r--ipfs-api-prelude/src/backend.rs27
-rw-r--r--ipfs-api-prelude/src/error.rs17
-rw-r--r--ipfs-api-prelude/src/request/mod.rs9
9 files changed, 55 insertions, 79 deletions
diff --git a/ipfs-api-backend-actix/Cargo.toml b/ipfs-api-backend-actix/Cargo.toml
index 3a616a6..22e4ba9 100644
--- a/ipfs-api-backend-actix/Cargo.toml
+++ b/ipfs-api-backend-actix/Cargo.toml
@@ -20,7 +20,5 @@ bytes = "1.0"
futures = "0.3"
http = "0.2"
ipfs-api-prelude = { version = "0.1.0", path = "../ipfs-api-prelude" }
-serde = { version = "1.0", features = ["derive"] }
-serde_json = "1.0"
-serde_urlencoded = "0.7"
+serde = "1.0"
thiserror = "1.0"
diff --git a/ipfs-api-backend-actix/src/backend.rs b/ipfs-api-backend-actix/src/backend.rs
index 6aa8f50..f61d70d 100644
--- a/ipfs-api-backend-actix/src/backend.rs
+++ b/ipfs-api-backend-actix/src/backend.rs
@@ -54,19 +54,16 @@ impl Backend for ActixBackend {
where
Req: ApiRequest,
{
- req.absolute_url(&self.base).and_then(|url| {
- let req = if let Some(form) = form {
- self.client
- .post(url)
- .timeout(ACTIX_REQUEST_TIMEOUT)
- .content_type(form.content_type())
- .send_body(multipart::client::multipart::Body::from(form))
- } else {
- self.client.post(url).timeout(ACTIX_REQUEST_TIMEOUT).send()
- };
-
- Ok(req)
- })
+ let url = req.absolute_url(&self.base)?;
+ let req = self.client.request(Req::METHOD, url);
+ let req = if let Some(form) = form {
+ req.content_type(form.content_type())
+ .send_body(multipart::Body::from(form))
+ } else {
+ req.timeout(ACTIX_REQUEST_TIMEOUT).send()
+ };
+
+ Ok(req)
}
fn get_header<'a>(res: &'a Self::HttpResponse, key: HeaderName) -> Option<&'a HeaderValue> {
diff --git a/ipfs-api-backend-actix/src/error.rs b/ipfs-api-backend-actix/src/error.rs
index 4cd9a25..aad2b05 100644
--- a/ipfs-api-backend-actix/src/error.rs
+++ b/ipfs-api-backend-actix/src/error.rs
@@ -6,7 +6,6 @@
// copied, modified, or distributed except according to those terms.
//
-use std::string::FromUtf8Error;
use thiserror::Error;
#[derive(Debug, Error)]
@@ -23,18 +22,6 @@ pub enum Error {
#[error("http error `{0}`")]
Http(#[from] http::Error),
- #[error("json parse error `{0}`")]
- Parse(#[from] serde_json::Error),
-
- #[error("utf8 decoding error `{0}`")]
- ParseUtf8(#[from] FromUtf8Error),
-
- #[error("uri error `{0}`")]
- Url(#[from] http::uri::InvalidUri),
-
- #[error("url encoding error `{0}`")]
- EncodeUrl(#[from] serde_urlencoded::ser::Error),
-
#[error("ipfs client error `{0}`")]
IpfsClientError(#[from] ipfs_api_prelude::Error),
}
diff --git a/ipfs-api-backend-hyper/Cargo.toml b/ipfs-api-backend-hyper/Cargo.toml
index 9ebd7d0..03ee234 100644
--- a/ipfs-api-backend-hyper/Cargo.toml
+++ b/ipfs-api-backend-hyper/Cargo.toml
@@ -20,7 +20,5 @@ hyper = { version = "0.14", features = ["http1", "http2", "c
hyper-multipart-rfc7578 = "0.5"
hyper-tls = "0.5"
ipfs-api-prelude = { version = "0.1.0", path = "../ipfs-api-prelude" }
-serde = { version = "1.0", features = ["derive"] }
-serde_json = "1.0"
-serde_urlencoded = "0.7"
+serde = "1.0"
thiserror = "1.0"
diff --git a/ipfs-api-backend-hyper/src/backend.rs b/ipfs-api-backend-hyper/src/backend.rs
index 047fbb6..bbe9a56 100644
--- a/ipfs-api-backend-hyper/src/backend.rs
+++ b/ipfs-api-backend-hyper/src/backend.rs
@@ -55,18 +55,18 @@ impl Backend for HyperBackend {
where
Req: ApiRequest,
{
- req.absolute_url(&self.base).and_then(move |url| {
- let builder = http::Request::builder();
- let builder = builder.method(Req::METHOD.clone()).uri(url);
-
- let req = if let Some(form) = form {
- form.set_body_convert::<hyper::Body, multipart::client::multipart::Body>(builder)
- } else {
- builder.body(hyper::Body::empty())
- };
-
- req.map_err(From::from)
- })
+ let url = req.absolute_url(&self.base)?;
+
+ let builder = http::Request::builder();
+ let builder = builder.method(Req::METHOD.clone()).uri(url);
+
+ let req = if let Some(form) = form {
+ form.set_body_convert::<hyper::Body, multipart::Body>(builder)
+ } else {
+ builder.body(hyper::Body::empty())
+ }?;
+
+ Ok(req)
}
fn get_header<'a>(res: &'a Self::HttpResponse, key: HeaderName) -> Option<&'a HeaderValue> {
diff --git a/ipfs-api-backend-hyper/src/error.rs b/ipfs-api-backend-hyper/src/error.rs
index 9db1959..4760fc4 100644
--- a/ipfs-api-backend-hyper/src/error.rs
+++ b/ipfs-api-backend-hyper/src/error.rs
@@ -6,7 +6,6 @@
// copied, modified, or distributed except according to those terms.
//
-use std::string::FromUtf8Error;
use thiserror::Error;
#[derive(Debug, Error)]
@@ -20,18 +19,6 @@ pub enum Error {
#[error("http error `{0}`")]
Http(#[from] http::Error),
- #[error("json parse error `{0}`")]
- Parse(#[from] serde_json::Error),
-
- #[error("utf8 decoding error `{0}`")]
- ParseUtf8(#[from] FromUtf8Error),
-
- #[error("uri error `{0}`")]
- Url(#[from] http::uri::InvalidUri),
-
- #[error("url encoding error `{0}`")]
- EncodeUrl(#[from] serde_urlencoded::ser::Error),
-
#[error("ipfs client error `{0}`")]
IpfsClientError(#[from] ipfs_api_prelude::Error),
}
diff --git a/ipfs-api-prelude/src/backend.rs b/ipfs-api-prelude/src/backend.rs
index bcc32e9..6a335f8 100644
--- a/ipfs-api-prelude/src/backend.rs
+++ b/ipfs-api-prelude/src/backend.rs
@@ -38,12 +38,7 @@ pub trait Backend: Default {
/// Error type for Result.
///
- type Error: Display
- + From<ApiError>
- + From<FromUtf8Error>
- + From<serde_json::Error>
- + From<crate::Error>
- + 'static;
+ type Error: Display + From<ApiError> + From<crate::Error> + 'static;
fn build_base_request<Req>(
&self,
@@ -82,10 +77,14 @@ pub trait Backend: Default {
fn process_error_from_body(body: Bytes) -> Self::Error {
match serde_json::from_slice::<ApiError>(&body) {
Ok(e) => e.into(),
- Err(_) => match String::from_utf8(body.to_vec()) {
- Ok(s) => crate::Error::UnrecognizedApiError(s).into(),
- Err(e) => e.into(),
- },
+ Err(_) => {
+ let err = match String::from_utf8(body.to_vec()) {
+ Ok(s) => crate::Error::UnrecognizedApiError(s),
+ Err(e) => crate::Error::from(e),
+ };
+
+ err.into()
+ }
}
}
@@ -97,7 +96,9 @@ pub trait Backend: Default {
for<'de> Res: 'static + Deserialize<'de>,
{
match status {
- StatusCode::OK => serde_json::from_slice(&body).map_err(From::from),
+ StatusCode::OK => serde_json::from_slice(&body)
+ .map_err(crate::Error::from)
+ .map_err(Self::Error::from),
_ => Err(Self::process_error_from_body(body)),
}
}
@@ -168,7 +169,9 @@ pub trait Backend: Default {
let (status, chunk) = self.request_raw(req, form).await?;
match status {
- StatusCode::OK => String::from_utf8(chunk.to_vec()).map_err(Self::Error::from),
+ StatusCode::OK => String::from_utf8(chunk.to_vec())
+ .map_err(crate::Error::from)
+ .map_err(Self::Error::from),
_ => Err(Self::process_error_from_body(chunk)),
}
}
diff --git a/ipfs-api-prelude/src/error.rs b/ipfs-api-prelude/src/error.rs
index 1b9bcaa..2c16c5b 100644
--- a/ipfs-api-prelude/src/error.rs
+++ b/ipfs-api-prelude/src/error.rs
@@ -6,7 +6,7 @@
// copied, modified, or distributed except according to those terms.
//
-use std::io;
+use std::{io, string::FromUtf8Error};
use thiserror::Error;
#[derive(Debug, Error)]
@@ -15,14 +15,23 @@ pub enum Error {
Io(#[from] io::Error),
#[error("utf8 decoding error `{0}`")]
+ ParseUtf8(#[from] FromUtf8Error),
+
+ #[error("json decoding error `{0}`")]
Parse(#[from] serde_json::Error),
- #[error("api returned an error while streaming: `{0}`")]
+ #[error("uri error `{0}`")]
+ Url(#[from] http::uri::InvalidUri),
+
+ #[error("url encoding error `{0}`")]
+ EncodeUrl(#[from] serde_urlencoded::ser::Error),
+
+ #[error("api returned an error while streaming `{0}`")]
StreamError(String),
- #[error("api got unrecognized trailer header: `{0}`")]
+ #[error("api got unrecognized trailer header `{0}`")]
UnrecognizedTrailerHeader(String),
- #[error("api returned an unknown error: `{0}`")]
+ #[error("api returned an unknown error `{0}`")]
UnrecognizedApiError(String),
}
diff --git a/ipfs-api-prelude/src/request/mod.rs b/ipfs-api-prelude/src/request/mod.rs
index 7fa1e4d..3a17539 100644
--- a/ipfs-api-prelude/src/request/mod.rs
+++ b/ipfs-api-prelude/src/request/mod.rs
@@ -98,7 +98,7 @@ mod swarm;
mod tar;
mod version;
-use http::uri::{InvalidUri, Uri};
+use http::uri::Uri;
use serde::Serialize;
/// A request that can be made against the Ipfs API.
@@ -117,10 +117,7 @@ pub trait ApiRequest: Serialize {
/// Creates the absolute URL for an API resource given the base path
/// of the service.
///
- fn absolute_url<Error>(&self, base: &Uri) -> Result<Uri, Error>
- where
- Error: From<InvalidUri> + From<serde_urlencoded::ser::Error>,
- {
+ fn absolute_url(&self, base: &Uri) -> Result<Uri, crate::Error> {
format!(
"{}{}?{}",
base,
@@ -128,6 +125,6 @@ pub trait ApiRequest: Serialize {
serde_urlencoded::to_string(self)?
)
.parse()
- .map_err(Error::from)
+ .map_err(crate::Error::from)
}
}