diff options
author | Ferris Tseng <ferristseng@fastmail.fm> | 2021-02-22 22:56:04 -0500 |
---|---|---|
committer | Ferris Tseng <ferristseng@fastmail.fm> | 2021-02-22 22:56:04 -0500 |
commit | 4ede307efb87bad2627190665279123e588a3494 (patch) | |
tree | 22795c2bc10d96e34a126863ef01e6b86ea9a5a3 | |
parent | 89519b4c5ce4839a362ab9ec9c6359f3c6aa844b (diff) |
centralize errors in prelude as much as possible
-rw-r--r-- | ipfs-api-backend-actix/Cargo.toml | 4 | ||||
-rw-r--r-- | ipfs-api-backend-actix/src/backend.rs | 23 | ||||
-rw-r--r-- | ipfs-api-backend-actix/src/error.rs | 13 | ||||
-rw-r--r-- | ipfs-api-backend-hyper/Cargo.toml | 4 | ||||
-rw-r--r-- | ipfs-api-backend-hyper/src/backend.rs | 24 | ||||
-rw-r--r-- | ipfs-api-backend-hyper/src/error.rs | 13 | ||||
-rw-r--r-- | ipfs-api-prelude/src/backend.rs | 27 | ||||
-rw-r--r-- | ipfs-api-prelude/src/error.rs | 17 | ||||
-rw-r--r-- | ipfs-api-prelude/src/request/mod.rs | 9 |
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) } } |