How to write idiomatic Rust error handling using AWS Rust SDK for DynamoDb?

1.2k Views Asked by At

I'm new to Rust with a background in Java, Groovy, and C. At this point in my Rust journey, I don't even know how to phrase the question in Google yet.

My question is, can someone give me an example of idiomatic Rust to replace my ugly code snippet below? It smells really bad.

The goal is to detect a ConditionalCheckFailedException when inserting a new row into AWS DynamoDb and then handle the error accordingly - not to bubble it up to the ultimate caller.

My code below is roughly based on an example found here: https://github.com/awslabs/aws-sdk-rust/blob/c0905d9c991bb38a9738f1ffcb74e200772afc12/sdk/examples/dynamo-add-item/src/main.rs#L128

use dynamodb::model::AttributeValue;
use dynamodb::Client;
use aws_hyper::SdkError;

  ...

    match request.send().await {
        Ok(_) => {
            println!("Added new row.");
            println!("");
        }
        Err(e) => {
            match e {
                SdkError::ConstructionFailure(ce) => eprintln!("ConstructionFailure:\n{:?}", ce),
                SdkError::DispatchFailure(df) => eprintln!("DispatchFailure:\n{:?}", df),
                SdkError::ResponseError{raw, err} => eprintln!("ResponseError:\n{:?}\n\n{:?}", raw, err),
                SdkError::ServiceError{raw: _, err} => {
                    match err.kind {
                        dynamodb::error::PutItemErrorKind::ConditionalCheckFailedException(ccfe) =>
                             eprintln!("ConditionalCheckFailedException: {:?}", ccfe),
                        _ => eprintln!("Don't know what kind.")

                    }
                },
            };
            process::exit(1);
        }
    };

  ...  

Thanks!!

1

There are 1 best solutions below

1
On

All the AWS rust sdk crates export all the possible error types for each service directly via the Error enum. For example, aws_sdk_dynamodb crate exports all the errors for DynamoDB service via the enum aws_sdk_dynamodb::Error.

You should be able to simplify your above code snippet as follows:

use aws_sdk_dynamodb::{
    error::PutItemErrorKind,
    model::{AttributeValue, Select},
    Error as DynamoDbError,
};

// send request and map the error to the `aws_sdk_dynamodb::Error` enum
let response = request.send().await.map_err(|e| DynamoDbError::from(e));

if let Err(PutItemErrorKind::ConditionalCheckFailedException(err)) = response {
    println!("ConditionalCheckFailedException: {}", err);
    // do error handling
    // ...
}