Error handling - AWS SDK for Rust

Error handling

Understanding how and when the AWS SDK for Rust returns errors is important to building high-quality applications using the SDK. The following sections describe the different errors you might encounter from the SDK and how to handle them appropriately.

Every operation returns a Result type with the error type set to SdkError<E, R = HttpResponse>. SdkError is an enum with several possible types, called variants.

Service errors

The most common type of error is SdkError::ServiceError. This error represents an error response from an AWS service. For example, if you try to get an object from Amazon S3 that doesn't exist, Amazon S3 returns an error response.

When you encounter an SdkError::ServiceError it means that your request was successfully sent to the AWS service but could not be processed. This can be because of errors in the request's parameters or because of issues on the service side.

The error response details are included in the error variant. The following example shows how to conveniently get at the underlying ServiceError variant and handle different error cases:

// Needed to access the '.code()' function on the error type: use aws_sdk_s3::error::ProvideErrorMetadata; let result = s3.get_object() .bucket("my-bucket") .key("my-key") .send() .await; match result { Ok(_output) => { /* Success. Do something with the output. */ } Err(err) => match err.into_service_error() { GetObjectError::InvalidObjectState(value) => { println!("invalid object state: {:?}", value); } GetObjectError::NoSuchKey(_) => { println!("object didn't exist"); } // err.code() returns the raw error code from the service and can be // used as a last resort for handling unmodeled service errors. err if err.code() == Some("SomeUnmodeledError") => {} err => return Err(err.into()) } };

Error metadata

Every service error has additional metadata that can be accessed by importing service-specific traits.

  • The <service>::error::ProvideErrorMetadata trait provides access to any available underlying raw error code and error message returned from the service.

You can also get information that might be useful when troubleshooting service errors:

  • The <service>::operation::RequestId trait adds extension methods to retrieve the unique AWS request ID that was generated by the service.

  • The <service>::operation::RequestIdExt trait adds the extended_request_id() method to get an additional, extended request ID.

Detailed error printing with DisplayErrorContext

Errors in the SDK are generally the result of a chain of failures such as:

  1. Dispatching a request has failed because the connector returned an error.

  2. The connector returned an error because the credentials provider returned an error.

  3. The credentials provider returned an error because it called a service and that service returned an error.

  4. The service returned an error because the credentials request didn't have the correct authorization.

By default, display of this error only outputs "dispatch failure". This lacks details that help troubleshoot the error. The SDK for Rust provides a simple error reporter called DisplayErrorContext.

When we wrap the error to be displayed and print it, DisplayErrorContext provides a much more detailed message similar to the following:

dispatch failure: other: Session token not found or invalid. DispatchFailure( DispatchFailure { source: ConnectorError { kind: Other(None), source: ProviderError( ProviderError { source: ProviderError( ProviderError { source: ServiceError( ServiceError { source: UnauthorizedException( UnauthorizedException { message: Some("Session token not found or invalid"), meta: ErrorMetadata { code: Some("UnauthorizedException"), message: Some("Session token not found or invalid"), extras: Some({"aws_request_id": "1b6d7476-f5ec-4a16-9890-7684ccee7d01"}) } } ), raw: Response { status: StatusCode(401), headers: Headers { headers: { "date": HeaderValue { _private: H0("Thu, 04 Jul 2024 07:41:21 GMT") }, "content-type": HeaderValue { _private: H0("application/json") }, "content-length": HeaderValue { _private: H0("114") }, "access-control-expose-headers": HeaderValue { _private: H0("RequestId") }, "access-control-expose-headers": HeaderValue { _private: H0("x-amzn-RequestId") }, "requestid": HeaderValue { _private: H0("1b6d7476-f5ec-4a16-9890-7684ccee7d01") }, "server": HeaderValue { _private: H0("AWS SSO") }, "x-amzn-requestid": HeaderValue { _private: H0("1b6d7476-f5ec-4a16-9890-7684ccee7d01") } } }, body: SdkBody { inner: Once( Some( b"{ \"message\":\"Session token not found or invalid\", \"__type\":\"com.amazonaws.switchboard.portal#UnauthorizedException\"}" ) ), retryable: true }, extensions: Extensions { extensions_02x: Extensions, extensions_1x: Extensions } } } ) } ) } ), connection: Unknown } } )