Skip to content

Commit

Permalink
chore: handle SdkError to show error message (#255)
Browse files Browse the repository at this point in the history
Signed-off-by: Ryota Sakamoto <[email protected]>
  • Loading branch information
ryota-sakamoto authored Jun 18, 2024
1 parent 9796a05 commit b5e8487
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 44 deletions.
14 changes: 14 additions & 0 deletions src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ use aws_config::{
meta::region::RegionProviderChain, retry::RetryConfig, BehaviorVersion, Region, SdkConfig,
};
use aws_sdk_dynamodb::types::{AttributeDefinition, TableDescription};
use aws_smithy_runtime_api::client::result::SdkError;
use aws_smithy_types::error::metadata::ProvideErrorMetadata;
use log::{debug, error, info};
use serde_yaml::Error as SerdeYAMLError;
use std::convert::{TryFrom, TryInto};
Expand Down Expand Up @@ -685,6 +687,18 @@ pub fn bye(code: i32, msg: &str) -> ! {
std::process::exit(code);
}

pub fn bye_with_sdk_error<E, R>(code: i32, error: SdkError<E, R>) -> !
where
E: fmt::Debug + ProvideErrorMetadata,
R: fmt::Debug,
{
match error.as_service_error() {
Some(service_error) => error!("service error occurred: {:?}", service_error.meta()),
None => error!("an error occurred: {:?}", error),
};
std::process::exit(code);
}

/* =================================================
Private functions
================================================= */
Expand Down
11 changes: 5 additions & 6 deletions src/bootstrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use aws_sdk_dynamodb::{
types::{AttributeValue, PutRequest, WriteRequest},
};
use futures::future::join_all;
use log::{debug, error};
use log::debug;

use brotli::Decompressor;
use serde_json::Value as JsonValue;
Expand Down Expand Up @@ -303,16 +303,15 @@ async fn prepare_table(cx: &app::Context, table_name: &str, keys: &[&str]) {
desc.table_status.unwrap()
);
}
Err(e) => match e.into_service_error() {
CreateTableError::ResourceInUseException(_) => println!(
Err(e) => match e.as_service_error() {
Some(CreateTableError::ResourceInUseException(_)) => println!(
"[skip] Table '{}' already exists in {} region, skipping to create new one.",
table_name,
cx.effective_region().await.as_ref()
),
e => {
_ => {
debug!("CreateTable API call got an error -- {:#?}", e);
error!("{}", e.to_string());
std::process::exit(1);
app::bye_with_sdk_error(1, e);
}
},
}
Expand Down
30 changes: 10 additions & 20 deletions src/control.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,7 @@ pub async fn list_tables_all_regions(cx: &app::Context) {
let ec2 = Ec2SdkClient::new(&config);
match ec2.describe_regions().send().await {
Err(e) => {
error!("{}", e.to_string());
std::process::exit(1);
app::bye_with_sdk_error(1, e);
}
Ok(res) => {
join_all(
Expand Down Expand Up @@ -154,8 +153,7 @@ pub async fn describe_table_api(cx: &app::Context, table_name: String) -> TableD
match ddb.describe_table().table_name(table_name).send().await {
Err(e) => {
debug!("DescribeTable API call got an error -- {:#?}", e);
error!("{}", e.into_service_error().meta());
std::process::exit(1);
app::bye_with_sdk_error(1, e);
}
Ok(res) => {
let desc: TableDescription = res.table.expect("This message should not be shown.");
Expand All @@ -177,8 +175,7 @@ pub async fn create_table(cx: &app::Context, name: String, given_keys: Vec<Strin
Ok(desc) => table::print_table_description(cx.effective_region().await.as_ref(), &desc),
Err(e) => {
debug!("CreateTable API call got an error -- {:#?}", e);
error!("{}", e.into_service_error());
std::process::exit(1);
app::bye_with_sdk_error(1, e);
}
}
}
Expand Down Expand Up @@ -259,8 +256,7 @@ pub async fn create_index(cx: &app::Context, index_name: String, given_keys: Vec
{
Err(e) => {
debug!("UpdateTable API call got an error -- {:#?}", e);
error!("{}", e.to_string());
std::process::exit(1);
app::bye_with_sdk_error(1, e);
}
Ok(res) => {
debug!("Returned result: {:#?}", res);
Expand Down Expand Up @@ -363,8 +359,7 @@ pub async fn update_table(
Ok(desc) => table::print_table_description(cx.effective_region().await.as_ref(), &desc),
Err(e) => {
debug!("UpdateTable API call got an error -- {:#?}", e);
error!("{}", e.to_string());
std::process::exit(1);
app::bye_with_sdk_error(1, e);
}
}
}
Expand Down Expand Up @@ -421,8 +416,7 @@ pub async fn delete_table(cx: &app::Context, name: String, skip_confirmation: bo
match ddb.delete_table().table_name(name).send().await {
Err(e) => {
debug!("DeleteTable API call got an error -- {:#?}", e);
error!("{}", e.into_service_error());
std::process::exit(1);
app::bye_with_sdk_error(1, e);
}
Ok(res) => {
debug!("Returned result: {:#?}", res);
Expand Down Expand Up @@ -463,7 +457,7 @@ pub async fn backup(cx: &app::Context, all_tables: bool) {
match req.send().await {
Err(e) => {
debug!("CreateBackup API call got an error -- {:#?}", e);
app::bye(1, &e.into_service_error().to_string());
app::bye_with_sdk_error(1, e);
}
Ok(res) => {
debug!("Returned result: {:#?}", res);
Expand Down Expand Up @@ -583,10 +577,7 @@ pub async fn restore(cx: &app::Context, backup_name: Option<String>, restore_nam
{
Err(e) => {
debug!("RestoreTableFromBackup API call got an error -- {:#?}", e);
app::bye(1, &e.into_service_error().to_string());
/* e.g. ... Possibly see "BackupInUse" error:
[2020-08-14T13:16:07Z DEBUG dy::control] RestoreTableFromBackup API call got an error -- Service( BackupInUse( "Backup is being used to restore another table: arn:aws:dynamodb:us-west-2:111111111111:table/Music/backup/01527492829107-81b9b3dd",))
*/
app::bye_with_sdk_error(1, e);
}
Ok(res) => {
debug!("Returned result: {:#?}", res);
Expand Down Expand Up @@ -614,8 +605,7 @@ async fn list_tables_api(cx: &app::Context, override_region: Option<&str>) -> Ve
match ddb.list_tables().send().await {
Err(e) => {
debug!("ListTables API call got an error -- {:#?}", e);
error!("{}", e.to_string());
std::process::exit(1);
app::bye_with_sdk_error(1, e);
}
// ListTables API returns blank array even if no table exists in a region.
Ok(res) => res.table_names.expect("This message should not be shown"),
Expand All @@ -635,7 +625,7 @@ async fn list_backups_api(cx: &app::Context, all_tables: bool) -> Vec<BackupSumm
match req.send().await {
Err(e) => {
debug!("ListBackups API call got an error -- {:#?}", e);
app::bye(1, &e.into_service_error().to_string());
app::bye_with_sdk_error(1, e);
}
Ok(res) => res
.backup_summaries
Expand Down
18 changes: 6 additions & 12 deletions src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,7 @@ pub async fn scan_api(
.await
.unwrap_or_else(|e| {
debug!("Scan API call got an error -- {:?}", e);
error!("{}", e.to_string());
std::process::exit(1);
app::bye_with_sdk_error(1, e);
})
}

Expand Down Expand Up @@ -274,8 +273,7 @@ pub async fn query(cx: &app::Context, params: QueryParams) {
}
Err(e) => {
debug!("Query API call got an error -- {:?}", e);
error!("{}", e.to_string());
std::process::exit(1);
app::bye_with_sdk_error(1, e);
}
}
}
Expand Down Expand Up @@ -331,8 +329,7 @@ pub async fn get_item(
},
Err(e) => {
debug!("GetItem API call got an error -- {:?}", e);
error!("{}", e.to_string());
std::process::exit(1);
app::bye_with_sdk_error(1, e);
}
}
}
Expand Down Expand Up @@ -384,8 +381,7 @@ pub async fn put_item(cx: &app::Context, pval: String, sval: Option<String>, ite
}
Err(e) => {
debug!("PutItem API call got an error -- {:?}", e);
error!("{}", e.into_service_error().meta());
std::process::exit(1);
app::bye_with_sdk_error(1, e);
}
}
}
Expand Down Expand Up @@ -420,8 +416,7 @@ pub async fn delete_item(cx: &app::Context, pval: String, sval: Option<String>)
}
Err(e) => {
debug!("Deletetem API call got an error -- {:?}", e);
error!("{}", e.to_string());
std::process::exit(1);
app::bye_with_sdk_error(1, e);
}
}
}
Expand Down Expand Up @@ -481,8 +476,7 @@ pub async fn update_item(
}
Err(e) => {
debug!("UpdateItem API call got an error -- {:?}", e);
error!("{}", e.to_string());
std::process::exit(1);
app::bye_with_sdk_error(1, e);
}
}
}
Expand Down
7 changes: 4 additions & 3 deletions tests/backup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@ async fn test_backup() -> Result<(), Box<dyn std::error::Error>> {
"To execute the command you must specify target table in one of following ways:",
));

// This error message only happens on DynamoDB Local which does not support backup feature.
tm.command()?
.args(["-r", "local", "backup", "--table", "non-existent-table"])
.assert()
.failure()
.stdout(predicate::str::contains(
// This error message only happens on DynamoDB Local which does not support backup feature.
"unhandled error (UnknownOperationException)",
.stderr(predicate::str::contains("UnknownOperationException"))
.stderr(predicate::str::contains(
"An unknown operation was requested.",
));

Ok(())
Expand Down
7 changes: 4 additions & 3 deletions tests/restore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@ async fn test_restore() -> Result<(), Box<dyn std::error::Error>> {
"To execute the command you must specify target table in one of following ways:",
));

// This error message only happens on DynamoDB Local which does not support backup feature.
tm.command()?
.args(["-r", "local", "restore", "--table", "non-existent-table"])
.assert()
.failure()
.stdout(predicate::str::contains(
// This error message only happens on DynamoDB Local which does not support backup feature.
"unhandled error (UnknownOperationException)",
.stderr(predicate::str::contains("UnknownOperationException"))
.stderr(predicate::str::contains(
"An unknown operation was requested.",
));

Ok(())
Expand Down

0 comments on commit b5e8487

Please sign in to comment.