mirror of https://github.com/smithy-lang/smithy-rs
Concrete body in SdkResult/SdkError (#247)
* Refactor out generic `B` parameter from SdkResult / SdkError * Switch to from_static * Add docs, fix old broken docs * Remove unused From<Bytes> bound * Rustfmt run
This commit is contained in:
parent
d75b7605b1
commit
6b38bf718e
|
@ -48,11 +48,11 @@ impl Default for AwsErrorRetryPolicy {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, E, B> ClassifyResponse<T, SdkError<E, B>> for AwsErrorRetryPolicy
|
impl<T, E> ClassifyResponse<T, SdkError<E>> for AwsErrorRetryPolicy
|
||||||
where
|
where
|
||||||
E: ProvideErrorKind,
|
E: ProvideErrorKind,
|
||||||
{
|
{
|
||||||
fn classify(&self, err: Result<&T, &SdkError<E, B>>) -> RetryKind {
|
fn classify(&self, err: Result<&T, &SdkError<E>>) -> RetryKind {
|
||||||
let (err, response) = match err {
|
let (err, response) = match err {
|
||||||
Ok(_) => return RetryKind::NotRetryable,
|
Ok(_) => return RetryKind::NotRetryable,
|
||||||
Err(SdkError::ServiceError { err, raw }) => (err, raw),
|
Err(SdkError::ServiceError { err, raw }) => (err, raw),
|
||||||
|
@ -88,6 +88,7 @@ where
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use crate::AwsErrorRetryPolicy;
|
use crate::AwsErrorRetryPolicy;
|
||||||
|
use smithy_http::middleware::ResponseBody;
|
||||||
use smithy_http::result::{SdkError, SdkSuccess};
|
use smithy_http::result::{SdkError, SdkSuccess};
|
||||||
use smithy_http::retry::ClassifyResponse;
|
use smithy_http::retry::ClassifyResponse;
|
||||||
use smithy_types::retry::{ErrorKind, ProvideErrorKind, RetryKind};
|
use smithy_types::retry::{ErrorKind, ProvideErrorKind, RetryKind};
|
||||||
|
@ -119,8 +120,14 @@ mod test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_err<E, B>(err: E, raw: http::Response<B>) -> Result<SdkSuccess<(), B>, SdkError<E, B>> {
|
fn make_err<E>(
|
||||||
Err(SdkError::ServiceError { err, raw })
|
err: E,
|
||||||
|
raw: http::Response<&'static str>,
|
||||||
|
) -> Result<SdkSuccess<()>, SdkError<E>> {
|
||||||
|
Err(SdkError::ServiceError {
|
||||||
|
err,
|
||||||
|
raw: raw.map(|b| ResponseBody::from_static(b)),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -21,7 +21,9 @@ impl Standard {
|
||||||
/// An https connection
|
/// An https connection
|
||||||
pub fn https() -> Self {
|
pub fn https() -> Self {
|
||||||
let https = HttpsConnector::new();
|
let https = HttpsConnector::new();
|
||||||
Self(Connector::Https(hyper::Client::builder().build::<_, SdkBody>(https)))
|
Self(Connector::Https(
|
||||||
|
hyper::Client::builder().build::<_, SdkBody>(https),
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A connection based on the provided `impl HttpService`
|
/// A connection based on the provided `impl HttpService`
|
||||||
|
|
|
@ -14,6 +14,7 @@ use aws_sig_auth::signer::SigV4Signer;
|
||||||
use smithy_http::body::SdkBody;
|
use smithy_http::body::SdkBody;
|
||||||
use smithy_http::operation::Operation;
|
use smithy_http::operation::Operation;
|
||||||
use smithy_http::response::ParseHttpResponse;
|
use smithy_http::response::ParseHttpResponse;
|
||||||
|
pub use smithy_http::result::{SdkError, SdkSuccess};
|
||||||
use smithy_http::retry::ClassifyResponse;
|
use smithy_http::retry::ClassifyResponse;
|
||||||
use smithy_http_tower::dispatch::DispatchLayer;
|
use smithy_http_tower::dispatch::DispatchLayer;
|
||||||
use smithy_http_tower::map_request::MapRequestLayer;
|
use smithy_http_tower::map_request::MapRequestLayer;
|
||||||
|
@ -27,9 +28,6 @@ use tower::{Service, ServiceBuilder, ServiceExt};
|
||||||
type BoxError = Box<dyn Error + Send + Sync>;
|
type BoxError = Box<dyn Error + Send + Sync>;
|
||||||
pub type StandardClient = Client<conn::Standard>;
|
pub type StandardClient = Client<conn::Standard>;
|
||||||
|
|
||||||
pub type SdkError<E> = smithy_http::result::SdkError<E, hyper::Body>;
|
|
||||||
pub type SdkSuccess<T> = smithy_http::result::SdkSuccess<T, hyper::Body>;
|
|
||||||
|
|
||||||
/// AWS Service Client
|
/// AWS Service Client
|
||||||
///
|
///
|
||||||
/// Hyper-based AWS Service Client. Most customers will want to construct a client with
|
/// Hyper-based AWS Service Client. Most customers will want to construct a client with
|
||||||
|
@ -138,8 +136,8 @@ where
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{Client, conn};
|
|
||||||
use crate::test_connection::TestConnection;
|
use crate::test_connection::TestConnection;
|
||||||
|
use crate::{conn, Client};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn construct_default_client() {
|
fn construct_default_client() {
|
||||||
|
|
|
@ -5,13 +5,13 @@
|
||||||
|
|
||||||
use http::header::{HeaderName, CONTENT_TYPE};
|
use http::header::{HeaderName, CONTENT_TYPE};
|
||||||
use http::Request;
|
use http::Request;
|
||||||
|
use protocol_test_helpers::{assert_ok, validate_body, MediaType};
|
||||||
use smithy_http::body::SdkBody;
|
use smithy_http::body::SdkBody;
|
||||||
use std::future::Ready;
|
use std::future::Ready;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
use tower::BoxError;
|
use tower::BoxError;
|
||||||
use protocol_test_helpers::{validate_body, MediaType, assert_ok};
|
|
||||||
|
|
||||||
type ConnectVec<B> = Vec<(http::Request<SdkBody>, http::Response<B>)>;
|
type ConnectVec<B> = Vec<(http::Request<SdkBody>, http::Response<B>)>;
|
||||||
|
|
||||||
|
@ -34,14 +34,18 @@ impl ValidateRequest {
|
||||||
}
|
}
|
||||||
let actual_str = std::str::from_utf8(actual.body().bytes().unwrap_or(&[]));
|
let actual_str = std::str::from_utf8(actual.body().bytes().unwrap_or(&[]));
|
||||||
let expected_str = std::str::from_utf8(expected.body().bytes().unwrap_or(&[]));
|
let expected_str = std::str::from_utf8(expected.body().bytes().unwrap_or(&[]));
|
||||||
let media_type = if actual.headers().get(CONTENT_TYPE).map(|v| v.to_str().unwrap().contains("json")).unwrap_or(false) {
|
let media_type = if actual
|
||||||
|
.headers()
|
||||||
|
.get(CONTENT_TYPE)
|
||||||
|
.map(|v| v.to_str().unwrap().contains("json"))
|
||||||
|
.unwrap_or(false)
|
||||||
|
{
|
||||||
MediaType::Json
|
MediaType::Json
|
||||||
} else {
|
} else {
|
||||||
MediaType::Other("unknown".to_string())
|
MediaType::Other("unknown".to_string())
|
||||||
};
|
};
|
||||||
match (actual_str, expected_str) {
|
match (actual_str, expected_str) {
|
||||||
(Ok(actual), Ok(expected)) =>
|
(Ok(actual), Ok(expected)) => assert_ok(validate_body(actual, expected, media_type)),
|
||||||
assert_ok(validate_body(actual, expected, media_type)),
|
|
||||||
_ => assert_eq!(actual.body().bytes(), expected.body().bytes()),
|
_ => assert_eq!(actual.body().bytes(), expected.body().bytes()),
|
||||||
};
|
};
|
||||||
assert_eq!(actual.uri(), expected.uri());
|
assert_eq!(actual.uri(), expected.uri());
|
||||||
|
|
|
@ -8,7 +8,7 @@ use aws_endpoint::{set_endpoint_resolver, DefaultAwsEndpointResolver};
|
||||||
use aws_http::user_agent::AwsUserAgent;
|
use aws_http::user_agent::AwsUserAgent;
|
||||||
use aws_http::AwsErrorRetryPolicy;
|
use aws_http::AwsErrorRetryPolicy;
|
||||||
use aws_hyper::test_connection::TestConnection;
|
use aws_hyper::test_connection::TestConnection;
|
||||||
use aws_hyper::{Client, RetryConfig, SdkError};
|
use aws_hyper::{Client, RetryConfig};
|
||||||
use aws_sig_auth::signer::OperationSigningConfig;
|
use aws_sig_auth::signer::OperationSigningConfig;
|
||||||
use aws_types::region::Region;
|
use aws_types::region::Region;
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
@ -18,6 +18,7 @@ use smithy_http::body::SdkBody;
|
||||||
use smithy_http::operation;
|
use smithy_http::operation;
|
||||||
use smithy_http::operation::Operation;
|
use smithy_http::operation::Operation;
|
||||||
use smithy_http::response::ParseHttpResponse;
|
use smithy_http::response::ParseHttpResponse;
|
||||||
|
use smithy_http::result::SdkError;
|
||||||
use smithy_types::retry::{ErrorKind, ProvideErrorKind};
|
use smithy_types::retry::{ErrorKind, ProvideErrorKind};
|
||||||
use std::convert::Infallible;
|
use std::convert::Infallible;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
|
@ -9,8 +9,8 @@ use aws_hyper::test_connection::TestConnection;
|
||||||
use aws_hyper::Client;
|
use aws_hyper::Client;
|
||||||
use http::Uri;
|
use http::Uri;
|
||||||
use kms::operation::GenerateRandom;
|
use kms::operation::GenerateRandom;
|
||||||
use kms::{Config, Region};
|
|
||||||
use smithy_http::body::SdkBody;
|
use smithy_http::body::SdkBody;
|
||||||
|
use kms::{Config, Region};
|
||||||
use std::time::{Duration, UNIX_EPOCH};
|
use std::time::{Duration, UNIX_EPOCH};
|
||||||
|
|
||||||
// TODO: having the full HTTP requests right in the code is a bit gross, consider something
|
// TODO: having the full HTTP requests right in the code is a bit gross, consider something
|
||||||
|
|
|
@ -10,6 +10,7 @@ use kms::Blob;
|
||||||
use smithy_http::result::{SdkError, SdkSuccess};
|
use smithy_http::result::{SdkError, SdkSuccess};
|
||||||
use smithy_http::retry::ClassifyResponse;
|
use smithy_http::retry::ClassifyResponse;
|
||||||
use smithy_types::retry::{ErrorKind, RetryKind};
|
use smithy_types::retry::{ErrorKind, RetryKind};
|
||||||
|
use smithy_http::middleware::ResponseBody;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn validate_sensitive_trait() {
|
fn validate_sensitive_trait() {
|
||||||
|
@ -29,9 +30,9 @@ fn errors_are_retryable() {
|
||||||
let conf = kms::Config::builder().build();
|
let conf = kms::Config::builder().build();
|
||||||
|
|
||||||
let op = CreateAlias::builder().build(&conf);
|
let op = CreateAlias::builder().build(&conf);
|
||||||
let err = Result::<SdkSuccess<CreateAliasOutput, &str>, SdkError<CreateAliasError, &str>>::Err(
|
let err = Result::<SdkSuccess<CreateAliasOutput>, SdkError<CreateAliasError>>::Err(
|
||||||
SdkError::ServiceError {
|
SdkError::ServiceError {
|
||||||
raw: http::Response::builder().body("resp").unwrap(),
|
raw: http::Response::builder().body(ResponseBody::from_static("resp")).unwrap(),
|
||||||
err,
|
err,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
|
@ -33,7 +33,7 @@ pub enum SendOperationError {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a `SendOperationError` into an `SdkError`
|
/// Convert a `SendOperationError` into an `SdkError`
|
||||||
impl<E, B> From<SendOperationError> for SdkError<E, B> {
|
impl<E> From<SendOperationError> for SdkError<E> {
|
||||||
fn from(err: SendOperationError) -> Self {
|
fn from(err: SendOperationError) -> Self {
|
||||||
match err {
|
match err {
|
||||||
SendOperationError::RequestDispatchError(e) => {
|
SendOperationError::RequestDispatchError(e) => {
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use crate::SendOperationError;
|
use crate::SendOperationError;
|
||||||
use bytes::Bytes;
|
|
||||||
use smithy_http::middleware::load_response;
|
use smithy_http::middleware::load_response;
|
||||||
use smithy_http::operation;
|
use smithy_http::operation;
|
||||||
use smithy_http::operation::Operation;
|
use smithy_http::operation::Operation;
|
||||||
|
@ -73,13 +72,13 @@ impl<S, O, T, E, B, R> tower::Service<operation::Operation<O, R>> for ParseRespo
|
||||||
where
|
where
|
||||||
S: Service<operation::Request, Response = http::Response<B>, Error = SendOperationError>,
|
S: Service<operation::Request, Response = http::Response<B>, Error = SendOperationError>,
|
||||||
S::Future: 'static,
|
S::Future: 'static,
|
||||||
B: http_body::Body + Unpin + From<Bytes> + 'static,
|
B: http_body::Body + Unpin + 'static,
|
||||||
B::Error: Into<BoxError>,
|
B::Error: Into<BoxError>,
|
||||||
O: ParseHttpResponse<B, Output = Result<T, E>> + 'static,
|
O: ParseHttpResponse<B, Output = Result<T, E>> + 'static,
|
||||||
E: Error,
|
E: Error,
|
||||||
{
|
{
|
||||||
type Response = smithy_http::result::SdkSuccess<T, B>;
|
type Response = smithy_http::result::SdkSuccess<T>;
|
||||||
type Error = smithy_http::result::SdkError<E, B>;
|
type Error = smithy_http::result::SdkError<E>;
|
||||||
type Future = BoxedResultFuture<Self::Response, Self::Error>;
|
type Future = BoxedResultFuture<Self::Response, Self::Error>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
|
|
|
@ -16,6 +16,43 @@ use bytes::{Buf, Bytes};
|
||||||
use http_body::Body;
|
use http_body::Body;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
|
|
||||||
|
/// Body for debugging purposes
|
||||||
|
///
|
||||||
|
/// When receiving data from the AWS services, it is often helpful to be able to see the response
|
||||||
|
/// body that a service generated. When the SDK has fully buffered the body into memory, this
|
||||||
|
/// facilitates straightforward debugging of the response.
|
||||||
|
///
|
||||||
|
/// Take care when calling the debug implementation to avoid printing responses from sensitive operations.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ResponseBody(Inner);
|
||||||
|
|
||||||
|
impl ResponseBody {
|
||||||
|
/// Load a response body from a static string
|
||||||
|
pub fn from_static(s: &'static str) -> Self {
|
||||||
|
ResponseBody(Inner::Bytes(Bytes::from_static(s.as_bytes())))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the raw bytes of this response
|
||||||
|
///
|
||||||
|
/// When the response has been buffered into memory, the bytes are returned
|
||||||
|
/// If the response is streaming or errored during the read process, `None` is returned.
|
||||||
|
pub fn bytes(&self) -> Option<&[u8]> {
|
||||||
|
match &self.0 {
|
||||||
|
Inner::Bytes(bytes) => Some(&bytes),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Private ResponseBody internals
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum Inner {
|
||||||
|
Bytes(bytes::Bytes),
|
||||||
|
Streaming,
|
||||||
|
Err,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
type BoxError = Box<dyn Error + Send + Sync>;
|
type BoxError = Box<dyn Error + Send + Sync>;
|
||||||
|
|
||||||
/// [`MapRequest`] defines a synchronous middleware that transforms an [`operation::Request`].
|
/// [`MapRequest`] defines a synchronous middleware that transforms an [`operation::Request`].
|
||||||
|
@ -72,22 +109,21 @@ pub trait MapRequest {
|
||||||
pub async fn load_response<B, T, E, O>(
|
pub async fn load_response<B, T, E, O>(
|
||||||
mut response: http::Response<B>,
|
mut response: http::Response<B>,
|
||||||
handler: &O,
|
handler: &O,
|
||||||
) -> Result<SdkSuccess<T, B>, SdkError<E, B>>
|
) -> Result<SdkSuccess<T>, SdkError<E>>
|
||||||
where
|
where
|
||||||
B: http_body::Body + Unpin,
|
B: http_body::Body + Unpin,
|
||||||
B: From<Bytes> + 'static,
|
|
||||||
B::Error: Into<BoxError>,
|
B::Error: Into<BoxError>,
|
||||||
O: ParseHttpResponse<B, Output = Result<T, E>>,
|
O: ParseHttpResponse<B, Output = Result<T, E>>,
|
||||||
{
|
{
|
||||||
if let Some(parsed_response) = handler.parse_unloaded(&mut response) {
|
if let Some(parsed_response) = handler.parse_unloaded(&mut response) {
|
||||||
return sdk_result(parsed_response, response);
|
return sdk_result(parsed_response, response.map(|_|ResponseBody(Inner::Streaming)));
|
||||||
}
|
}
|
||||||
|
|
||||||
let body = match read_body(response.body_mut()).await {
|
let body = match read_body(response.body_mut()).await {
|
||||||
Ok(body) => body,
|
Ok(body) => body,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err(SdkError::ResponseError {
|
return Err(SdkError::ResponseError {
|
||||||
raw: response,
|
raw: response.map(|_|ResponseBody(Inner::Err)),
|
||||||
err: e.into(),
|
err: e.into(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -95,7 +131,7 @@ where
|
||||||
|
|
||||||
let response = response.map(|_| Bytes::from(body));
|
let response = response.map(|_| Bytes::from(body));
|
||||||
let parsed = handler.parse_loaded(&response);
|
let parsed = handler.parse_loaded(&response);
|
||||||
sdk_result(parsed, response.map(B::from))
|
sdk_result(parsed, response.map(|body|ResponseBody(Inner::Bytes(body))))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn read_body<B: http_body::Body>(body: B) -> Result<Vec<u8>, B::Error> {
|
async fn read_body<B: http_body::Body>(body: B) -> Result<Vec<u8>, B::Error> {
|
||||||
|
@ -112,10 +148,10 @@ async fn read_body<B: http_body::Body>(body: B) -> Result<Vec<u8>, B::Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert a `Result<T, E>` into an `SdkResult` that includes the raw HTTP response
|
/// Convert a `Result<T, E>` into an `SdkResult` that includes the raw HTTP response
|
||||||
fn sdk_result<T, E, B>(
|
fn sdk_result<T, E>(
|
||||||
parsed: Result<T, E>,
|
parsed: Result<T, E>,
|
||||||
raw: http::Response<B>,
|
raw: http::Response<ResponseBody>,
|
||||||
) -> Result<SdkSuccess<T, B>, SdkError<E, B>> {
|
) -> Result<SdkSuccess<T>, SdkError<E>> {
|
||||||
match parsed {
|
match parsed {
|
||||||
Ok(parsed) => Ok(SdkSuccess { raw, parsed }),
|
Ok(parsed) => Ok(SdkSuccess { raw, parsed }),
|
||||||
Err(err) => Err(SdkError::ServiceError { raw, err }),
|
Err(err) => Err(SdkError::ServiceError { raw, err }),
|
||||||
|
|
|
@ -6,37 +6,19 @@
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::{Debug, Display, Formatter};
|
use std::fmt::{Debug, Display, Formatter};
|
||||||
|
use crate::middleware::ResponseBody;
|
||||||
|
|
||||||
type BoxError = Box<dyn Error + Send + Sync>;
|
type BoxError = Box<dyn Error + Send + Sync>;
|
||||||
|
|
||||||
/// Successful Sdk Result
|
/// Successful Sdk Result
|
||||||
///
|
|
||||||
/// Typically, transport implementations will type alias (or entirely wrap / transform) this type
|
|
||||||
/// plugging in a concrete body implementation, eg:
|
|
||||||
/// ```rust
|
|
||||||
/// # mod hyper {
|
|
||||||
/// # pub struct Body;
|
|
||||||
/// # }
|
|
||||||
/// type SdkSuccess<O> = smithy_http::result::SdkSuccess<O, hyper::Body>;
|
|
||||||
/// ```
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SdkSuccess<O, B> {
|
pub struct SdkSuccess<O> {
|
||||||
pub raw: http::Response<B>,
|
pub raw: http::Response<ResponseBody>,
|
||||||
pub parsed: O,
|
pub parsed: O,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Failing Sdk Result
|
/// Failing Sdk Result
|
||||||
///
|
|
||||||
/// Typically, transport implementations will type alias (or entirely wrap / transform) this type
|
|
||||||
/// by specifying a concrete body implementation:
|
|
||||||
/// ```rust
|
|
||||||
/// # mod hyper {
|
|
||||||
/// # pub struct Body;
|
|
||||||
/// # }
|
|
||||||
/// type SdkError<E> = smithy_http::result::SdkError<E, hyper::Body>;
|
|
||||||
/// ```
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum SdkError<E, B> {
|
pub enum SdkError<E> {
|
||||||
/// The request failed during construction. It was not dispatched over the network.
|
/// The request failed during construction. It was not dispatched over the network.
|
||||||
ConstructionFailure(BoxError),
|
ConstructionFailure(BoxError),
|
||||||
|
|
||||||
|
@ -47,28 +29,26 @@ pub enum SdkError<E, B> {
|
||||||
/// A response was received but it was not parseable according the the protocol (for example
|
/// A response was received but it was not parseable according the the protocol (for example
|
||||||
/// the server hung up while the body was being read)
|
/// the server hung up while the body was being read)
|
||||||
ResponseError {
|
ResponseError {
|
||||||
raw: http::Response<B>,
|
raw: http::Response<ResponseBody>,
|
||||||
err: BoxError,
|
err: BoxError,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// An error response was received from the service
|
/// An error response was received from the service
|
||||||
ServiceError { err: E, raw: http::Response<B> },
|
ServiceError { err: E, raw: http::Response<ResponseBody> },
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, B> Display for SdkError<E, B>
|
impl<E> Display for SdkError<E>
|
||||||
where
|
where
|
||||||
E: Error,
|
E: Error,
|
||||||
B: Debug,
|
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, "{:?}", self)
|
write!(f, "{:?}", self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E, B> Error for SdkError<E, B>
|
impl<E> Error for SdkError<E>
|
||||||
where
|
where
|
||||||
E: Error + 'static,
|
E: Error + 'static,
|
||||||
B: Debug,
|
|
||||||
{
|
{
|
||||||
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
fn source(&self) -> Option<&(dyn Error + 'static)> {
|
||||||
match self {
|
match self {
|
||||||
|
|
Loading…
Reference in New Issue