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
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
trait provides access to any available underlying raw error code and error message returned from the service.<service>
::error::ProvideErrorMetadata-
For Amazon S3, this trait is
aws_sdk_s3::error::ProvideErrorMetadata
.
-
You can also get information that might be useful when troubleshooting service errors:
-
The
trait adds extension methods to retrieve the unique AWS request ID that was generated by the service.<service>
::operation::RequestId-
For Amazon S3, this trait is
aws_sdk_s3::operation::RequestId
.
-
-
The
trait adds the<service>
::operation::RequestIdExtextended_request_id()
method to get an additional, extended request ID.-
Only supported by some services.
-
For Amazon S3, this trait is
aws_sdk_s3::operation::RequestIdExt
.
-
Detailed error printing with DisplayErrorContext
Errors in the SDK are generally the result of a chain of failures such as:
-
Dispatching a request has failed because the connector returned an error.
-
The connector returned an error because the credentials provider returned an error.
-
The credentials provider returned an error because it called a service and that service returned an error.
-
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
.
-
The
struct adds functionality to output the full error context.<service>
::error::DisplayErrorContext-
For Amazon S3, this struct is
aws_sdk_s3::error::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
}
}
)