

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

# 处理 Rust AWS 开发工具包中的错误
<a name="error-handling"></a>

了解 适用于 Rust 的 AWS SDK 返回错误的方式和时间对于使用 SDK 构建高质量的应用程序非常重要。以下各节介绍了您在 SDK 中可能遇到的各种错误以及如何正确处理它们。

每个操作都会返回一个错误类型设置为 [https://docs.rs/aws-smithy-runtime-api/latest/aws_smithy_runtime_api/client/result/enum.SdkError.html](https://docs.rs/aws-smithy-runtime-api/latest/aws_smithy_runtime_api/client/result/enum.SdkError.html) 的 `Result` 类型。`SdkError` 是一个包含几种可能类型的枚举，称为变体。

## 服务错误
<a name="serviceErrors"></a>

最常见的错误类型是 [https://docs.rs/aws-smithy-runtime-api/latest/aws_smithy_runtime_api/client/result/enum.SdkError.html#variant.ServiceError](https://docs.rs/aws-smithy-runtime-api/latest/aws_smithy_runtime_api/client/result/enum.SdkError.html#variant.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())
    }
};
```

## 错误元数据
<a name="errorMetadata"></a>

 每个服务错误都有额外的元数据，可以通过导入特定于服务的特性来访问这些元数据。
+ `<service>::error::ProvideErrorMetadata` 特性提供了对服务返回的任何可用底层原始错误代码和错误消息的访问权限。
  + 对于 Amazon S3，这个特性是 [https://docs.rs/aws-sdk-s3/latest/aws_sdk_s3/error/trait.ProvideErrorMetadata.html](https://docs.rs/aws-sdk-s3/latest/aws_sdk_s3/error/trait.ProvideErrorMetadata.html)。

您还可以获取一些对服务错误故障排除可能有用的信息：
+ `<service>::operation::RequestId`该特征添加了用于检索服务生成的唯一 AWS 请求 ID 的扩展方法。
  + 对于 Amazon S3，这个特性是 [https://docs.rs/aws-sdk-s3/latest/aws_sdk_s3/operation/trait.RequestId.html](https://docs.rs/aws-sdk-s3/latest/aws_sdk_s3/operation/trait.RequestId.html)。
+ `<service>::operation::RequestIdExt` 特性添加了 `extended_request_id()` 方法，用于获取额外的扩展请求 ID。
  + 仅部分服务支持。
  +  对于 Amazon S3，这个特性是 [https://docs.rs/aws-sdk-s3/latest/aws_sdk_s3/operation/trait.RequestIdExt.html](https://docs.rs/aws-sdk-s3/latest/aws_sdk_s3/operation/trait.RequestIdExt.html)。

## 使用 `DisplayErrorContext` 打印详细的错误
<a name="displayErrorContext"></a>

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

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

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

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

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

默认情况下，显示此错误仅输出“分派失败”。这缺少有助于解决错误的详细信息。适用于 Rust 的 SDK 提供了一个名为 `DisplayErrorContext` 的简单错误报告程序。
+  `<service>::error::DisplayErrorContext` 结构增加了输出完整错误上下文的功能。
  + 对于 Amazon S3，这个结构是 [https://docs.rs/aws-sdk-s3/latest/aws_sdk_s3/error/struct.DisplayErrorContext.html](https://docs.rs/aws-sdk-s3/latest/aws_sdk_s3/error/struct.DisplayErrorContext.html)。

当我们封装要显示的错误并打印出来时，`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 
        } 
    }
)
```