From 1548ee47ab1420859d6a4541f0d4de8b36dee5b4 Mon Sep 17 00:00:00 2001 From: Nigel Lee Date: Thu, 11 Aug 2022 10:50:55 +0800 Subject: [PATCH] feat: Add path to errors --- src/client/base/async_std.rs | 6 ++++-- src/client/base/tokio.rs | 10 +++++++--- src/client/stripe.rs | 21 ++++++++++++++++----- src/error.rs | 6 +++--- 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/client/base/async_std.rs b/src/client/base/async_std.rs index 6b1a09c8f..4782a535c 100644 --- a/src/client/base/async_std.rs +++ b/src/client/base/async_std.rs @@ -45,7 +45,8 @@ impl AsyncStdClient { Box::pin(async move { let bytes = send_inner(&client, request, &strategy).await?; - serde_json::from_slice(&bytes).map_err(StripeError::from) + let json_deserializer = &mut serde_json::Deserializer::from_slice(&bytes); + serde_path_to_error::deserialize(json_deserializer).map_err(StripeError::from) }) } } @@ -99,7 +100,8 @@ async fn send_inner( if !status.is_success() { tries += 1; - last_error = serde_json::from_slice(&bytes) + let json_deserializer = &mut serde_json::Deserializer::from_slice(&bytes); + last_error = serde_path_to_error::deserialize(json_deserializer) .map(|mut e: ErrorResponse| { e.error.http_status = status.into(); StripeError::from(e.error) diff --git a/src/client/base/tokio.rs b/src/client/base/tokio.rs index 21a4ac47d..019c0e5d8 100644 --- a/src/client/base/tokio.rs +++ b/src/client/base/tokio.rs @@ -71,7 +71,8 @@ impl TokioClient { Box::pin(async move { let bytes = send_inner(&client, request, &strategy).await?; - serde_json::from_slice(&bytes).map_err(StripeError::from) + let json_deserializer = &mut serde_json::Deserializer::from_slice(&bytes); + serde_path_to_error::deserialize(json_deserializer).map_err(StripeError::from) }) } } @@ -127,7 +128,8 @@ async fn send_inner( if !status.is_success() { tries += 1; - last_error = serde_json::from_slice(&bytes) + let json_deserializer = &mut serde_json::Deserializer::from_slice(&bytes); + last_error = serde_path_to_error::deserialize(json_deserializer) .map(|mut e: ErrorResponse| { e.error.http_status = status.into(); StripeError::from(e.error) @@ -297,7 +299,9 @@ mod tests { mock.assert_hits_async(1).await; match res { - Err(StripeError::JSONSerialize(x)) => println!("{:?}", x), + Err(StripeError::JSONSerialize(err)) => { + println!("Error: {:?} Path: {:?}", err.inner(), err.path().to_string()) + } _ => panic!("Expected stripe error {:?}", res), } } diff --git a/src/client/stripe.rs b/src/client/stripe.rs index 635d3a394..67a7d055e 100644 --- a/src/client/stripe.rs +++ b/src/client/stripe.rs @@ -132,10 +132,15 @@ impl Client { ) -> Response { let url = self.url(path); let mut req = self.create_request(Method::Post, url); - req.set_body(match serde_qs::to_string(&form) { - Err(e) => return err(StripeError::QueryStringSerialize(e)), - Ok(body) => Body::from_string(body), - }); + + let mut params_buffer = Vec::new(); + let qs_ser = &mut serde_qs::Serializer::new(&mut params_buffer); + serde_path_to_error::serialize(&form, qs_ser).map_err(StripeError::from)?; + + let body = std::str::from_utf8(params_buffer.as_slice()).unwrap().to_string(); + + req.set_body(Body::from_string(body)); + req.insert_header("content-type", "application/x-www-form-urlencoded"); self.client.execute::(req, &self.strategy) } @@ -148,7 +153,13 @@ impl Client { fn url_with_params(&self, path: &str, params: P) -> Result { let mut url = self.url(path); - let params = serde_qs::to_string(¶ms).map_err(StripeError::from)?; + + let mut params_buffer = Vec::new(); + let qs_ser = &mut serde_qs::Serializer::new(&mut params_buffer); + serde_path_to_error::serialize(¶ms, qs_ser).map_err(StripeError::from)?; + + let params = std::str::from_utf8(params_buffer.as_slice()).unwrap().to_string(); + url.set_query(Some(¶ms)); Ok(url) } diff --git a/src/error.rs b/src/error.rs index b1b59169a..27286ed7a 100644 --- a/src/error.rs +++ b/src/error.rs @@ -11,9 +11,9 @@ pub enum StripeError { #[error("error reported by stripe: {0}")] Stripe(#[from] RequestError), #[error("error serializing or deserializing a querystring: {0}")] - QueryStringSerialize(#[from] serde_qs::Error), - #[error("error serializing or deserializing a request: {0}")] - JSONSerialize(#[from] serde_json::Error), + QueryStringSerialize(#[from] serde_path_to_error::Error), + #[error("error serializing or deserializing a request")] + JSONSerialize(#[from] serde_path_to_error::Error), #[error("attempted to access an unsupported version of the api")] UnsupportedVersion, #[error("error communicating with stripe: {0}")]