Unverified Commit 336670b4 authored by Russell Cohen's avatar Russell Cohen Committed by GitHub
Browse files

Create a Top-Level Error Generator (#282)

* This is weird

* impl Error for Top Level Errors

* Disable 1.51 clippy lints. Not sure why they are showing up in this PR that hasn't bumped the rustc version

* clean impl display, top level errors send/sync

* Assert errors are send+sync

* Make futures Send
parent 60841ef2
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -96,7 +96,7 @@ where
    /// access the raw response use `call_raw`.
    pub async fn call<O, T, E, Retry>(&self, input: Operation<O, Retry>) -> Result<T, SdkError<E>>
    where
        O: ParseHttpResponse<hyper::Body, Output = Result<T, E>> + Send + Clone + 'static,
        O: ParseHttpResponse<hyper::Body, Output = Result<T, E>> + Send + Sync + Clone + 'static,
        E: Error + ProvideErrorKind,
        Retry: ClassifyResponse<SdkSuccess<T>, SdkError<E>>,
    {
@@ -112,7 +112,7 @@ where
        input: Operation<O, Retry>,
    ) -> Result<SdkSuccess<R>, SdkError<E>>
    where
        O: ParseHttpResponse<hyper::Body, Output = Result<R, E>> + Send + Clone + 'static,
        O: ParseHttpResponse<hyper::Body, Output = Result<R, E>> + Send + Sync + Clone + 'static,
        E: Error + ProvideErrorKind,
        Retry: ClassifyResponse<SdkSuccess<R>, SdkError<E>>,
    {
+14 −3
Original line number Diff line number Diff line
@@ -242,7 +242,7 @@ where
    Handler: Clone,
    R: ClassifyResponse<SdkSuccess<T>, SdkError<E>>,
{
    type Future = Pin<Box<dyn Future<Output = Self>>>;
    type Future = Pin<Box<dyn Future<Output = Self> + Send>>;

    fn retry(
        &self,
@@ -263,7 +263,7 @@ where
            next
        }
        .instrument(tracing::info_span!("retry", kind = &debug(retry)));
        Some(Box::pin(fut))
        Some(check_send_sync(Box::pin(fut)))
    }

    fn clone_request(&self, req: &Operation<Handler, R>) -> Option<Operation<Handler, R>> {
@@ -271,16 +271,27 @@ where
    }
}

fn check_send_sync<T: Send>(t: T) -> T {
    t
}

#[cfg(test)]
mod test {
    use crate::retry::{RetryConfig, RetryHandlerFactory};
    use crate::retry::{RetryConfig, RetryHandler, RetryHandlerFactory};
    use smithy_types::retry::ErrorKind;
    use std::time::Duration;

    fn assert_send_sync<T: Send + Sync>() {}

    fn test_config() -> RetryConfig {
        RetryConfig::default().with_base(|| 1_f64)
    }

    #[test]
    fn retry_handler_send_sync() {
        assert_send_sync::<RetryHandler>()
    }

    #[test]
    fn eventual_success() {
        let policy = RetryHandlerFactory::new(test_config()).new_handler();
+1 −2
Original line number Diff line number Diff line
@@ -14,7 +14,6 @@ import software.amazon.smithy.rust.codegen.rustlang.RustMetadata
import software.amazon.smithy.rust.codegen.rustlang.RustModule
import software.amazon.smithy.rust.codegen.rustlang.RustType
import software.amazon.smithy.rust.codegen.rustlang.RustWriter
import software.amazon.smithy.rust.codegen.rustlang.Writable
import software.amazon.smithy.rust.codegen.rustlang.asType
import software.amazon.smithy.rust.codegen.rustlang.documentShape
import software.amazon.smithy.rust.codegen.rustlang.render
@@ -29,7 +28,7 @@ import software.amazon.smithy.rust.codegen.smithy.generators.LibRsCustomization
import software.amazon.smithy.rust.codegen.smithy.generators.LibRsSection
import software.amazon.smithy.rust.codegen.smithy.generators.ProtocolConfig
import software.amazon.smithy.rust.codegen.smithy.generators.builderSymbol
import software.amazon.smithy.rust.codegen.smithy.generators.errorSymbol
import software.amazon.smithy.rust.codegen.smithy.generators.error.errorSymbol
import software.amazon.smithy.rust.codegen.smithy.rustType
import software.amazon.smithy.rust.codegen.util.inputShape
import software.amazon.smithy.rust.codegen.util.outputShape
+1 −3
Original line number Diff line number Diff line
@@ -3,14 +3,12 @@
 * SPDX-License-Identifier: Apache-2.0.
 */

use std::error::Error;

use dynamodb::model::{
    AttributeDefinition, KeySchemaElement, KeyType, ProvisionedThroughput, ScalarAttributeType,
};

#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
async fn main() -> Result<(), dynamodb::Error> {
    let client = dynamodb::Client::from_env();
    let tables = client.list_tables().send().await?;

+24 −3
Original line number Diff line number Diff line
@@ -3,7 +3,8 @@
 * SPDX-License-Identifier: Apache-2.0.
 */

use kms::operation::CreateAlias;
use kms::error::CreateAliasError;
use kms::operation::{CreateAlias, GenerateRandom};
use kms::output::GenerateRandomOutput;
use kms::Blob;
use smithy_http::middleware::ResponseBody;
@@ -22,11 +23,28 @@ fn validate_sensitive_trait() {
    );
}

fn assert_send_sync<T: Send + Sync + 'static>() {}
fn assert_send_fut<T: Send + 'static>(_: T) {}

#[test]
fn types_are_send_sync() {
    assert_send_sync::<kms::Error>();
    assert_send_sync::<kms::SdkError<CreateAliasError>>();
    assert_send_sync::<kms::error::CreateAliasError>();
    assert_send_sync::<kms::output::CreateAliasOutput>();
    assert_send_sync::<kms::Client>();
    assert_send_sync::<GenerateRandom>();
    assert_send_fut(kms::Client::from_env().list_keys().send());
}

/// Parse a semi-real response body and assert that the correct retry status is returned
#[test]
fn errors_are_retryable() {
    let conf = kms::Config::builder().build();
    let (_, parts) = CreateAlias::builder().build(&conf).expect("valid request").into_request_response();
    let (_, parts) = CreateAlias::builder()
        .build(&conf)
        .expect("valid request")
        .into_request_response();
    let http_response = http::Response::builder()
        .status(400)
        .body(r#"{ "code": "LimitExceededException" }"#)
@@ -45,7 +63,10 @@ fn errors_are_retryable() {
#[test]
fn unmodeled_errors_are_retryable() {
    let conf = kms::Config::builder().build();
    let (_, parts) = CreateAlias::builder().build(&conf).expect("valid request").into_request_response();
    let (_, parts) = CreateAlias::builder()
        .build(&conf)
        .expect("valid request")
        .into_request_response();
    let http_response = http::Response::builder()
        .status(400)
        .body(r#"{ "code": "ThrottlingException" }"#)
Loading