处理适用于 Rust 的 AWS SDK 中的错误 - 适用于 Rust 的 AWS SDK

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

处理适用于 Rust 的 AWS SDK 中的错误

要使用 SDK 构建高质量的应用程序,必须了解适用于 Rust 的 AWS SDK 在什么情况下会返回错误以及它以什么方式返回错误。以下各节介绍了您在 SDK 中可能遇到的各种错误以及如何正确处理它们。

每个操作都会返回一个错误类型设置为 SdkError<E, R = HttpResponse>Result 类型。SdkError 是一个包含几种可能类型的枚举,称为变体。

服务错误

最常见的错误类型是 SdkError::ServiceError。该错误是指来自 AWS 服务的错误响应。例如,如果您尝试从 Amazon S3 获取不存在的对象,则 Amazon S3 会返回错误响应。

当您遇到 SdkError::ServiceError 时,则意味着您的请求已成功发送到 AWS 服务,但无法成功处理。这可能是因为请求的参数中存在错误,或者是因为服务端的问题。

错误变体中包含错误响应详细信息。以下示例展示了如何便捷地获取底层 ServiceError 变体并处理不同的错误情况:

// 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()) } };

错误元数据

每个服务错误都有额外的元数据,可以通过导入特定于服务的特性来访问这些元数据。

  • <service>::error::ProvideErrorMetadata 特性提供了对服务返回的任何可用底层原始错误代码和错误消息的访问权限。

您还可以获取一些对服务错误故障排除可能有用的信息:

  • <service>::operation::RequestId 特性添加了扩展方法,用于检索服务生成的唯一 AWS 请求 ID。

  • <service>::operation::RequestIdExt 特性添加了 extended_request_id() 方法,用于获取额外的扩展请求 ID。

使用 DisplayErrorContext 打印详细的错误

SDK 中的错误通常是由一连串失败造成的,例如:

  1. 连接器返回了一个错误,分派请求失败。

  2. 连接器返回了一个错误,因为凭证提供程序返回了一个错误。

  3. 凭证提供程序返回了一个错误,因为它调用了一个服务,而该服务返回了一个错误。

  4. 该服务返回了一个错误,因为凭证请求没有正确的授权。

默认情况下,显示此错误仅输出“分派失败”。这缺少有助于解决错误的详细信息。适用于 Rust 的 SDK 提供了一个名为 DisplayErrorContext 的简单错误报告程序。

当我们封装要显示的错误并打印出来时,DisplayErrorContext 会提供更详细的消息,类似于以下内容:

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 } } )