Skip to content

Commit

Permalink
Add 'as-service-error' to simplify handling of specific error conditi…
Browse files Browse the repository at this point in the history
…ons (#3333)

## Motivation and Context
aws-sdk-rust#1010

## Description
Add `as-service-error` helper function to cleanup handling of service
error

## Testing
UT

## Checklist
<!--- If a checkbox below is not applicable, then please DELETE it
rather than leaving it unchecked -->
- [x] I have updated `CHANGELOG.next.toml` if I made changes to the
smithy-rs codegen or runtime crates
- [x] I have updated `CHANGELOG.next.toml` if I made changes to the AWS
SDK, generated SDK code, or SDK runtime crates

----

_By submitting this pull request, I confirm that you can use, modify,
copy, and redistribute this contribution, under the terms of your
choice._
  • Loading branch information
rcoh authored Jan 4, 2024
1 parent 7541fe7 commit e652d6a
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 1 deletion.
12 changes: 12 additions & 0 deletions CHANGELOG.next.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,18 @@ references = ["smithy-rs#3252", "smithy-rs#3312"]
meta = { "breaking" = false, "tada" = false, "bug" = true }
author = "milesziemer"

[[smithy-rs]]
message = "Add `as_service_err()` to `SdkError` to allow checking the type of an error is without taking ownership."
references = ["smithy-rs#3333", "aws-sdk-rust#998", "aws-sdk-rust#1010"]
meta = { "breaking" = false, "tada" = true, "bug" = false }
author = "rcoh"

[[aws-sdk-rust]]
message = "Add `as_service_err()` to `SdkError` to allow checking the type of an error is without taking ownership."
references = ["smithy-rs#3333", "aws-sdk-rust#998", "aws-sdk-rust#1010"]
meta = { "breaking" = false, "tada" = true, "bug" = false }
author = "rcoh"

[[smithy-rs]]
message = """`requireEndpointResolver: false` is no longer required to remove the need for an endpoint resolver. Instead, `"awsSdkBuilder"` (default false), now _removes_ that requirement."""
references = ["smithy-rs#3292"]
Expand Down
4 changes: 3 additions & 1 deletion aws/sdk/integration-tests/s3/tests/status-200-errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use aws_credential_types::provider::SharedCredentialsProvider;
use aws_credential_types::Credentials;
use aws_sdk_s3::Client;
use aws_smithy_runtime::assert_str_contains;
use aws_smithy_runtime::client::http::test_util::infallible_client_fn;
use aws_smithy_types::body::SdkBody;
use aws_smithy_types::error::metadata::ProvideErrorMetadata;
Expand Down Expand Up @@ -37,5 +38,6 @@ async fn status_200_errors() {
.send()
.await
.expect_err("should fail");
assert_eq!(error.into_service_error().code(), Some("SlowDown"));
assert_eq!(error.as_service_error().unwrap().code(), Some("SlowDown"));
assert_str_contains!(format!("{:?}", error), "Please reduce your request rate");
}
30 changes: 30 additions & 0 deletions rust-runtime/aws-smithy-runtime-api/src/client/result.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,36 @@ impl<E, R> SdkError<E, R> {
}
}

/// Returns a reference underlying service error `E` if there is one
///
/// # Examples
/// ```no_run
/// # use aws_smithy_runtime_api::client::result::SdkError;
/// # #[derive(Debug)] enum GetObjectError { NoSuchKey(()), Other(()) }
/// # impl std::fmt::Display for GetObjectError {
/// # fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { unimplemented!() }
/// # }
/// # impl std::error::Error for GetObjectError {}
/// # impl GetObjectError {
/// # fn is_not_found(&self) -> bool { true }
/// # }
/// # fn example() -> Result<(), GetObjectError> {
/// # let sdk_err = SdkError::service_error(GetObjectError::NoSuchKey(()), ());
/// if sdk_err.as_service_error().map(|e|e.is_not_found()) == Some(true) {
/// println!("the object doesn't exist");
/// // return None, or handle this error specifically
/// }
/// // ... handle other error cases, happy path, etc.
/// # Ok(())
/// # }
/// ```
pub fn as_service_error(&self) -> Option<&E> {
match self {
Self::ServiceError(err) => Some(&err.source),
_ => None,
}
}

/// Converts this error into its error source.
///
/// If there is no error source, then `Err(Self)` is returned.
Expand Down

0 comments on commit e652d6a

Please sign in to comment.