Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade guidance for error changes #1950

Closed
jdisanti opened this issue Nov 4, 2022 · 0 comments
Closed

Upgrade guidance for error changes #1950

jdisanti opened this issue Nov 4, 2022 · 0 comments

Comments

@jdisanti
Copy link
Collaborator

jdisanti commented Nov 4, 2022

This is an upgrade guide and summary of changes made in smithy-rs#1926, that will be linked in the release notes.

At a high level, errors were refactored to:

  • Be either actionable or informational. Actionable errors can be matched upon, leading to different program flow. Informational errors indicate why a failure occurred, but are not intended to be matched upon.
  • No longer print error sources in Display impls. A DisplayErrorContext utility has been re-exported in the types module to easily log or print the entire error source chain.
  • Reliably return their cause/source in their Error::cause/Error::source impl

Additionally, a convenience was added to SdkError to make matching on the error kind easier (shown below in SdkError Changes).

Example of using DisplayErrorContext

When logging an error from the SDK, it is recommended that you either wrap the error in DisplayErrorContext, or use another error reporter library that visits the error's cause/source chain.

use my_generated_crate::types::DisplayErrorContext;

println!("Something broke in the SDK: {}", DisplayErrorContext(&err));

SdkError Changes

SdkError previously had struct variants, but those have been replaced with actual structs. This impacts matching on SdkError. Previously, you might have something like:

let result = client
	.get_object()
	.bucket(BUCKET_NAME)
	.key("some-key")
	.send()
	.await;
match result {
	Ok(_output) => { /* Do something with the output */ }
	Err(err) => match err {
		SdkError::ServiceError {
			err: ref service_err,
			..
		} => match service_err {
			GetObjectError {
				kind: GetObjectErrorKind::InvalidObjectState(value),
				..
			} => {
				println!("invalid object state: {:?}", value);
			}
			GetObjectError {
				kind: GetObjectErrorKind::NoSuchKey(_),
				..
			} => {
				println!("object didn't exist");
			}
			GetObjectError { .. } if service_err.code() == Some("SomeUnmodeledError") => {}
			_ => Err(err)?,
		},
		_ => Err(err)?,
	},
}

In the latest version, SdkError has an into_service_error() method that allows this to be simplified slightly:

let result = client
    .get_object()
    .bucket(BUCKET_NAME)
    .key("some-key")
    .send()
    .await;
match result {
    Ok(_output) => { /* Do something with the output */ }
    Err(err) => match err.into_service_error() {
        GetObjectError {
            kind: GetObjectErrorKind::InvalidObjectState(value),
            ..
        } => {
            println!("invalid object state: {:?}", value);
        }
        GetObjectError {
            kind: GetObjectErrorKind::NoSuchKey(_),
            ..
        } => {
            println!("object didn't exist");
        }
        err @ GetObjectError { .. } if err.code() == Some("SomeUnmodeledError") => {}
        err @ _ => return Err(err.into()),
    },
}

Full List of Changes

  • The Unhandled variant on generated errors now has an Unhandled new type rather than a Box<dyn Error + Send + Sync + 'static> as its tuple member.
  • aws_smithy_async::future::timeout::TimedOutError no longer implements Copy, Clone, Eq, and PartialEq.
  • aws_smithy_checksums::Error was renamed to aws_smithy_checksums::error::UnknownChecksumAlgorithmError, and is no longer matchable.
  • aws_smithy_eventstream::error::Error is no longer matchable.
  • aws_smithy_http::endpoint::Error was renamed to aws_smithy_http::endpoint::error::ResolveEndpointError
  • SdkError variants can no longer be directly constructed. There are now functions on SdkError to construct each individual variant.
  • aws_smithy_http::byte_stream::Error was moved to aws_smithy_http::byte_stream::error::Error, and is no longer matchable.
  • aws_smithy_http::endpoint::Error was renamed to aws_smithy_http::endpoint::error::ResolveEndpointError, and is no longer matchable.
  • aws_smithy_http::endpoint::InvalidEndpoint were moved into aws_smithy_http::endpoint::error, and is no longer matchable.
  • aws_smithy_http::event_stream::Error was renamed to aws_smithy_http::event_stream::ReceiverError.
  • aws_smithy_http::operation::BuildError was renamed to aws_smithy_http::operation::error::BuildError, and is no longer matchable.
  • aws_smithy_http::operation::SerializationError was renamed to aws_smithy_http::operation::error::SerializationError, and is no longer matchable.
  • aws_smithy_json::deserialize::Error was renamed to aws_smithy_json::deserialize::error::DeserializeError, and is no longer matchable.
  • aws_smithy_json::escape::EscapeError is no longer matchable.
  • aws_smithy_types::base64::DecodeError is no longer matchable, and no longer implements Clone, Eq, and PartialEq.
  • aws_smithy_types::TryFromNumberError moved to aws_smithy_types::error::TryFromNumberError, and is no longer matchable.
  • aws_smithy_types::date_time::format::DateTimeParseError is no longer matchable.
  • aws_smithy_types::date_time::format::DateTimeFormatError is no longer matchable.
  • aws_smithy_types::primitive::PrimitiveParseError no longer implements Eq, PartialEq, and Clone.
  • aws_smithy_types::retry::RetryModeParseErr was renamed to RetryModeParseError
  • aws_smithy_types::retry::RetryConfigErr and aws_smithy_types::timeout::error::ConfigError were deleted since they were no longer referenced.
  • aws_smithy_types_convert::date_time::Error is no longer matchable.
  • aws_smithy_xml::decode::XmlError was renamed to XmlDecodeError, and is no longer matchable.
  • aws_smithy_xml::encode::Error was renamed to XmlEncodeError.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant