

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 使用 適用於 Go 的 AWS SDK
<a name="using"></a>

了解 適用於 Go 的 AWS SDK 在應用程式中使用 進行程式設計的常見和建議方法。

**Topics**
+ [建構服務用戶端](#constructing-a-service-client)
+ [呼叫 服務操作](#calling-service-operations)
+ [同時使用 服務用戶端](#concurrently-using-service-clients)
+ [使用操作分頁器](#using-operation-paginators)
+ [使用等待程式](#using-waiters)
+ [處理 SDK 中的錯誤](handle-errors.md)

## 建構服務用戶端
<a name="constructing-a-service-client"></a>

 您可以使用服務用戶端 Go 套件中可用的 `New`或 `NewFromConfig`函數來建構服務用戶端。每個函數都會傳回結構`Client`類型，其中包含叫用服務 APIs的方法。`New` 和`NewFromConfig`每個 提供相同的一組可設定選項來建構服務用戶端，但提供稍有不同的建構模式，我們將在以下各節中查看。

### NewFromConfig
<a name="newfromconfig"></a>

 `NewFromConfig` 函數提供一致的界面，用於使用 [aws.Config](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#Config) 建構服務用戶端。`aws.Config` 您可以使用 [config.LoadDefaultConfig](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/config#LoadDefaultConfig) 載入 。如需建構 的詳細資訊`aws.Config`，請參閱 [設定軟體開發套件](configure-gosdk.md)。下列範例示範如何使用 `aws.Config`和 `NewFromConfig`函數建構 Amazon S3 服務用戶端：

```
import "context"
    import "github.com/aws/aws-sdk-go-v2/config"
    import "github.com/aws/aws-sdk-go-v2/service/s3"
    
    // ...
    
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        panic(err)
    }
    
    client := s3.NewFromConfig(cfg)
```

#### 覆寫組態
<a name="overriding-configuration"></a>

 `NewFromConfig` 可以採用一或多個功能引數，以變更用戶端的組態`Options`結構。這可讓您進行特定覆寫，例如變更區域，或修改服務特定選項，例如 Amazon S3 `UseAccelerate`選項。例如：

```
import "context"
    import "github.com/aws/aws-sdk-go-v2/config"
    import "github.com/aws/aws-sdk-go-v2/service/s3"
    
    // ...
    
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        panic(err)
    }
    
    client := s3.NewFromConfig(cfg, func(o *s3.Options) {
        o.Region = "us-west-2"
        o.UseAccelerate = true
    })
```

 覆寫用戶端`Options`值取決於函數引數提供給 的順序`NewFromConfig`。

### 新增
<a name="new"></a>

**注意**  
 `New` 被視為更進階的用戶端建構形式。我們建議您使用 `NewFromConfig`進行用戶端建構，因為它允許使用 `aws.Config` 結構進行建構。這樣就不需要為應用程式所需的每個服務用戶端建構`Options`結構執行個體。

 `New` 函數是用戶端建構函數，提供了一個介面，用於僅使用用戶端套件`Options`結構來定義用戶端的組態選項來建構用戶端。例如，使用 建構 Amazon S3 用戶端`New`：

```
import "github.com/aws/aws-sdk-go-v2/aws"
    import "github.com/aws/aws-sdk-go-v2/credentials"
    import "github.com/aws/aws-sdk-go-v2/service/s3"
    
    // ...
    
    client := s3.New(s3.Options{
        Region:      "us-west-2",
        Credentials: aws.NewCredentialsCache(credentials.NewStaticCredentialsProvider(accessKey, secretKey, "")),
    })
```

#### 覆寫組態
<a name="overriding-configuration-1"></a>

 `New` 可以採用一或多個功能引數，以變更用戶端的組態`Options`結構。這可讓您進行特定覆寫，例如變更區域或修改服務特定選項，例如 Amazon S3 `UseAccelerate`選項。例如：

```
import "github.com/aws/aws-sdk-go-v2/aws"
    import "github.com/aws/aws-sdk-go-v2/credentials"
    import "github.com/aws/aws-sdk-go-v2/service/s3"
    
    // ...
    
    options := s3.Options{
        Region:      "us-west-2",
        Credentials: aws.NewCredentialsCache(credentials.NewStaticCredentialsProvider(accessKey, secretKey, "")),
    }
    
    client := s3.New(options, func(o *s3.Options) {
        o.Region = "us-east-1"
        o.UseAccelerate = true
    })
```

 覆寫用戶端`Options`值取決於函數引數提供給 的順序`New`。

## 呼叫 服務操作
<a name="calling-service-operations"></a>

 擁有服務用戶端執行個體之後，您可以使用它來呼叫服務的操作。例如，若要呼叫 Amazon S3 `GetObject`操作：

```
response, err := client.GetObject(context.TODO(), &s3.GetObjectInput{
        Bucket: aws.String("amzn-s3-demo-bucket"),
        Key:    aws.String("obj-key"),
    })
```

 當您呼叫服務操作時，軟體開發套件會同步驗證輸入、序列化請求、使用登入資料簽署請求、將其傳送至 AWS，然後還原序列化回應或錯誤。在大多數情況下，您可以直接呼叫 服務操作。每個服務操作用戶端方法都會傳回操作回應結構和錯誤界面類型。在嘗試存取服務操作的回應結構之前，您應該一律檢查`error`類型以判斷是否發生錯誤。

### 將參數傳遞至服務操作
<a name="passing-parameters-to-a-service-operation"></a>

 每個服務操作方法都採用[內容。內容](https://golang.org/pkg/context/#Context)值可用於設定 SDK 將遵守的請求截止日期。此外，每個服務操作都會採用服務個別 Go `<OperationName>Input` 套件中找到的結構。您可以使用 操作輸入結構傳入 API 輸入參數。

 操作輸入結構可以具有輸入參數，例如標準 Go 數值、布林值、字串、映射和清單類型。在更複雜的 API 操作中，服務可能會有更複雜的輸入參數建模。這些其他類型，例如服務特定的結構和列舉值，可在服務的 `types` Go 套件中找到。

 此外，服務可能會區分 Go 類型的預設值，以及使用者是否設定該值。在這些情況下，輸入參數可能需要您將指標參考傳遞至有問題的類型。對於標準 Go 類型，例如數字、布林值和字串，[aws](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws) 中提供 `<Type>`和 `From<Type>` 便利函數，以簡化此轉換。例如，[aws.String](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#String) 可用來將 轉換為需要指向字串的輸入參數`string``*string`類型。反之，[aws.ToString](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws#ToString) 可用來將 `*string` 轉換為 ，`string`同時提供保護，避免取消參考 nil 指標。這些`To<Type>`函數在處理服務回應時很有幫助。

 讓我們看看如何使用 Amazon S3 用戶端呼叫 `GetObject` API 的範例，並使用 `types`套件和`aws.<Type>`協助程式建構我們的輸入。

```
import "context"
    import "github.com/aws/aws-sdk-go-v2/config"
    import "github.com/aws/aws-sdk-go-v2/service/s3"
    import "github.com/aws/aws-sdk-go-v2/service/s3/types"
    
    // ...
    
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        panic(err)
    }
    
    client := s3.NewFromConfig(cfg)
    
    resp, err := client.GetObject(context.TODO(), &s3.GetObjectInput{
        Bucket:       aws.String("amzn-s3-demo-bucket"),
        Key:          aws.String("keyName"),
        RequestPayer: types.RequestPayerRequester,
    })
```

### 覆寫操作呼叫的用戶端選項
<a name="overriding-client-options"></a>

 與使用功能引數建構用戶端期間修改用戶端操作選項的方式類似，在呼叫操作方法時，可以透過向服務操作方法提供一或多個功能引數來修改用戶端選項。此動作是並行安全的，不會影響用戶端上的其他並行操作。

 例如，若要覆寫從 "us-west-2" 到 "us-east-1" 的用戶端區域：

```
cfg, err := config.LoadDefaultConfig(context.TODO(), config.WithRegion("us-west-2"))
    if err != nil {
        log.Printf("error: %v", err)
        return
    }
    
    client := s3.NewFromConfig(cfg)
    
    params := &s3.GetObjectInput{
        // ...
    }
    
    resp, err := client.GetObject(context.TODO(), params, func(o *Options) {
        o.Region = "us-east-1"
    })
```

### 處理操作回應
<a name="handling-operation-responses"></a>

 每個服務操作都有相關聯的輸出結構，其中包含服務的操作回應成員。輸出結構遵循下列命名模式 `<OperationName>Output`。有些操作可能沒有為其操作輸出定義的成員。呼叫服務操作後，應一律檢查傳回`error`引數類型，以判斷呼叫服務操作時是否發生錯誤。傳回的錯誤範圍從用戶端輸入驗證錯誤到傳回給用戶端的服務端錯誤回應。如果用戶端傳回非 nil 錯誤，則不應存取操作的輸出結構。

 例如，若要記錄操作錯誤並提早從呼叫函數傳回：

```
response, err := client.GetObject(context.TODO())
    if err != nil {
        log.Printf("GetObject error: %v", err)
        return
    }
```

 如需錯誤處理的詳細資訊，包括如何檢查特定錯誤類型，請參閱 TODO 

#### 使用 的回應 `io.ReadCloser`
<a name="responses-with-ioreadcloser"></a>

 有些 API 操作會傳回回應結構，其中包含 的輸出成員`io.ReadCloser`。這種情況適用於在 HTTP 回應本身內文中公開其輸出某些元素的 API 操作。

 例如，Amazon S3 `GetObject`操作會傳回回應，其`Body`成員是 ，`io.ReadCloser`用於存取物件承載。

**警告**  
 您必須一律`Close()`使用任何`io.ReadCloser`輸出成員，無論您是否已使用其內容。否則，可能會洩漏資源，並可能在未來對呼叫的操作讀取回應主體產生問題。

```
resp, err := s3svc.GetObject(context.TODO(), &s3.GetObjectInput{...})
    if err != nil {
        // handle error
        return
    }
    // Make sure to always close the response Body when finished
    defer resp.Body.Close()
    
    decoder := json.NewDecoder(resp.Body)
    if err := decoder.Decode(&myStruct); err != nil {
        // handle error
        return
    }
```

#### 回應中繼資料
<a name="response-metadata"></a>

 所有服務操作輸出結構都包含類型[為 middleware.Metadata](https://pkg.go.dev/github.com/aws/smithy-go/middleware#Metadata) `ResultMetadata`的成員。 軟體開發套件中介軟體`middleware.Metadata`會使用 來提供來自非由服務建模之服務回應的其他資訊。這包括中繼資料，例如 `RequestID`。例如，若要擷取與服務回應`RequestID`相關聯的 ，以協助 AWS Support 對請求進行故障診斷：

```
import "fmt"
    import "log"
    import "github.com/aws/aws-sdk-go-v2/aws/middleware"
    import "github.com/aws/aws-sdk-go-v2/service/s3"
    
    // ..
    
    resp, err := client.GetObject(context.TODO(), &s3.GetObjectInput{
        // ...
    })
    if err != nil {
        log.Printf("error: %v", err)
        return
    }
    
    requestID, ok := middleware.GetRequestIDMetadata(resp.ResultMetadata)
    if !ok {
        fmt.Println("RequestID not included with request")
    }
    
    fmt.Printf("RequestID: %s\n", requestID)
```

## 同時使用 服務用戶端
<a name="concurrently-using-service-clients"></a>

 您可以建立同時使用相同服務用戶端傳送多個請求的 goroutine。您可以使用服務用戶端搭配任意數量的 goroutine。

 在下列範例中，Amazon S3 服務用戶端用於多個 goroutine。此範例會同時將兩個物件上傳至 Amazon S3 儲存貯體。

```
import "context"
    import "log"
    import "strings"
    import "github.com/aws/aws-sdk-go-v2/config"
    import "github.com/aws/aws-sdk-go-v2/service/s3"
    
    // ...
    
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Printf("error: %v", err)
        return
    }
    
    client := s3.NewFromConfig(cfg)
    
    type result struct {
        Output *s3.PutObjectOutput
        Err    error
    }
    
    results := make(chan result, 2)
    
    var wg sync.WaitGroup
    wg.Add(2)
    
    go func() {
    defer wg.Done()
        output, err := client.PutObject(context.TODO(), &s3.PutObjectInput{
            Bucket: aws.String("amzn-s3-demo-bucket"),
            Key:    aws.String("foo"),
            Body:   strings.NewReader("foo body content"),
        })
        results <- result{Output: output, Err: err}
    }()
    
    go func() {
        defer wg.Done()
        output, err := client.PutObject(context.TODO(), &s3.PutObjectInput{
            Bucket: aws.String("amzn-s3-demo-bucket"),
            Key:    aws.String("bar"),
            Body:   strings.NewReader("bar body content"),
        })
        results <- result{Output: output, Err: err}
    }()
    
    wg.Wait()
    
    close(results)
    
    for result := range results {
        if result.Err != nil {
            log.Printf("error: %v", result.Err)
            continue
        }
        fmt.Printf("etag: %v", aws.ToString(result.Output.ETag))
    }
```

## 使用操作分頁器
<a name="using-operation-paginators"></a>

 一般而言，當您擷取項目清單時，您可能需要檢查權杖或標記的輸出結構，以確認 AWS 服務是否傳回請求中的所有結果。如果字符或標記存在，您可以使用它來請求下一頁的結果。您可以使用服務套件的可用分頁器類型，而不是管理這些字符或標記。

 分頁程式協助程式可用於支援的 服務操作，可在服務用戶端的 Go 套件中找到。若要為支援的操作建構分頁程式，請使用 `New<OperationName>Paginator`函數。分頁器建構函數採用服務 `Client`、操作的`<OperationName>Input`輸入參數，以及一組選用的功能引數，可讓您設定其他選用分頁器設定。

 傳回的操作分頁器類型提供便利的方式來逐一查看分頁操作，直到您到達最後一個頁面，或找到應用程式正在搜尋的項目為止。分頁程式類型有兩種方法： `HasMorePages`和 `NextPage`。`true`如果尚未擷取第一個頁面，或者可以使用 操作擷取其他頁面，則 會`HasMorePages`傳回布林值。若要擷取操作的第一頁或後續頁面，必須呼叫 `NextPage`操作。 會`NextPage`取得`context.Context`並傳回操作輸出和任何對應的錯誤。如同用戶端操作方法傳回參數，在嘗試使用傳回的回應結構之前，應一律檢查傳回錯誤。請參閱 [處理操作回應](#handling-operation-responses)。

 下列範例使用分頁器，從 `ListObjectsV2` `ListObjectV2`操作列出最多三頁的物件金鑰。每個頁面最多包含 10 個金鑰，由`Limit`分頁器選項定義。

```
import "context"
    import "log"
    import "github.com/aws/aws-sdk-go-v2/config"
    import "github.com/aws/aws-sdk-go-v2/aws"
    import "github.com/aws/aws-sdk-go-v2/service/s3"
    
    // ...
    
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Printf("error: %v", err)
        return
    }
    
    client := s3.NewFromConfig(cfg)
    
    params := &s3.ListObjectsV2Input{
        Bucket: aws.String("amzn-s3-demo-bucket"),
    }
    
    paginator := s3.NewListObjectsV2Paginator(client, params, func(o *s3.ListObjectsV2PaginatorOptions) {
        o.Limit = 10
    })
    
    pageNum := 0
    for paginator.HasMorePages() && pageNum < 3 {
        output, err := paginator.NextPage(context.TODO())
        if err != nil {
            log.Printf("error: %v", err)
            return
        }
        for _, value := range output.Contents {
            fmt.Println(*value.Key)
        }
        pageNum++
    }
```

 與用戶端操作方法類似，可以透過提供一或多個功能引數給 來修改請求區域之類的用戶端選項`NextPage`。如需在呼叫 操作時覆寫用戶端選項的詳細資訊，請參閱 [覆寫操作呼叫的用戶端選項](#overriding-client-options)。

## 使用等待程式
<a name="using-waiters"></a>

 與非同步 AWS APIs 互動時，您通常需要等待特定資源變成可用，才能對其執行進一步的動作。

 例如，Amazon DynamoDB `CreateTable` API 會立即傳回 CREATING 的 TableStatus，而且在資料表狀態轉換為 之前，您無法叫用讀取或寫入操作`ACTIVE`。

 編寫邏輯以持續輪詢資料表狀態可能會很麻煩且容易出錯。等待程式有助於消除複雜性，並且是為您處理輪詢任務的簡單 APIs。

 例如，您可以使用等待程式輪詢 DynamoDB 資料表是否已建立並準備好進行寫入操作。

```
import "context"
    import "fmt"
    import "log"
    import "time"
    import "github.com/aws/aws-sdk-go-v2/aws"
    import "github.com/aws/aws-sdk-go-v2/config"
    import "github.com/aws/aws-sdk-go-v2/service/dynamodb"
    
    // ...
    
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Printf("error: %v", err)
        return
    }
    
    client := dynamodb.NewFromConfig(cfg)
    
    // we create a waiter instance by directly passing in a client
    // that satisfies the waiters client Interface. 
    waiter :=  dynamodb.NewTableExistsWaiter(client)
    
    // params is the input to api operation used by the waiter
    params := &dynamodb.DescribeTableInput {
        TableName: aws.String("test-table")
    }
    
    // maxWaitTime is the maximum wait time, the waiter will wait for 
    // the resource status.
    maxWaitTime := 5 * time.Minutes
    
    // Wait will poll until it gets the resource status, or max wait time 
    // expires.
    err := waiter.Wait(context.TODO(), params, maxWaitTime)  
    if err != nil {
        log.Printf("error: %v", err)
        return 
    }
    fmt.Println("Dynamodb table is now ready for write operations")
```

### 覆寫等待程式組態
<a name="overriding-waiter-configuration"></a>

 根據預設，軟體開發套件會使用針對不同 APIs AWS 的服務所定義的最佳值所設定的最小延遲和最大延遲值。您可以在等待程式建構期間提供功能選項，或在叫用等待程式操作時，覆寫等待程式組態。

 例如，在等待程式建構期間覆寫等待程式組態 

```
import "context"
    import "fmt"
    import "log"
    import "time"
    import "github.com/aws/aws-sdk-go-v2/aws"
    import "github.com/aws/aws-sdk-go-v2/config"
    import "github.com/aws/aws-sdk-go-v2/service/dynamodb"
    
    // ...
    
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Printf("error: %v", err)
        return
    }
    
    client := dynamodb.NewFromConfig(cfg)
    
    // we create a waiter instance by directly passing in a client
    // that satisfies the waiters client Interface. 
    waiter :=  dynamodb.NewTableExistsWaiter(client, func (o *dynamodb.TableExistsWaiterOptions) {
        
        // override minimum delay to 10 seconds
        o.MinDelay = 10 * time.Second
        
        // override maximum default delay to 300 seconds
        o.MaxDelay = 300 * time.Second
    })
```

每個等待器上的 `Wait`函數也會採用功能選項。與上述範例類似，您可以覆寫每個`Wait`請求的等待程式組態。

```
// params is the input to api operation used by the waiter
    params := &dynamodb.DescribeTableInput {
        TableName: aws.String("test-table")
    }
    
    // maxWaitTime is the maximum wait time, the waiter will wait for 
    // the resource status.
    maxWaitTime := 5 * time.Minutes
    
    // Wait will poll until it gets the resource status, or max wait time 
    // expires.
    err := waiter.Wait(context.TODO(), params, maxWaitTime, func (o *dynamodb.TableExistsWaiterOptions) {
    
        // override minimum delay to 5 seconds
        o.MinDelay = 5 * time.Second
    
        // override maximum default delay to 120 seconds
        o.MaxDelay = 120 * time.Second
    })
    if err != nil {
        log.Printf("error: %v", err)
        return 
    }
    fmt.Println("Dynamodb table is now ready for write operations")
```

### 進階等待程式組態覆寫
<a name="advanced-waiter-configuration-overrides"></a>

 您還可以透過提供自訂可重試函數來自訂等待程式預設行為。等待程式特定的選項也提供`APIOptions`[自訂操作中介軟體](middleware.md#writing-a-custom-middleware)的選項。

 例如，設定進階等待程式覆寫。

```
import "context"
    import "fmt"
    import "log"
    import "time"
    import "github.com/aws/aws-sdk-go-v2/aws"
    import "github.com/aws/aws-sdk-go-v2/config"
    import "github.com/aws/aws-sdk-go-v2/service/dynamodb"
    import "github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
    // ...
    
    cfg, err := config.LoadDefaultConfig(context.TODO())
    if err != nil {
        log.Printf("error: %v", err)
        return
    }
    
    client := dynamodb.NewFromConfig(cfg)
    
    // custom retryable defines if a waiter state is retryable or a terminal state.
    // For example purposes, we will configure the waiter to not wait 
    // if table status is returned as `UPDATING`
    customRetryable := func(ctx context.Context, params *dynamodb.DescribeTableInput, 
        output *dynamodb.DescribeTableOutput, err error) (bool, error) {
        if output.Table != nil {
            if output.Table.TableStatus == types.TableStatusUpdating {
                // if table status is `UPDATING`, no need to wait
                return false, nil   
            }
        }
    }
    
    // we create a waiter instance by directly passing in a client
    // that satisfies the waiters client Interface. 
    waiter :=  dynamodb.NewTableExistsWaiter(client, func (o *dynamodb.TableExistsWaiterOptions) {
        
        // override the service defined waiter-behavior
        o.Retryable = customRetryable
    })
```

# 處理 適用於 Go 的 AWS SDK V2 中的錯誤
<a name="handle-errors"></a>

 適用於 Go 的 AWS SDK 會傳回滿足 Go `error` 介面類型的錯誤。您可以使用 `Error()`方法取得 SDK 錯誤訊息的格式化字串，無需任何特殊處理。開發套件傳回的錯誤可能會實作 `Unwrap`方法。軟體開發套件會使用 `Unwrap`方法，為錯誤提供額外的內容資訊，同時提供基礎錯誤或錯誤鏈的存取權。`Unwrap` 方法應與 [errors.As](https://golang.org/pkg/errors#As) 搭配使用，以處理取消包裝的錯誤鏈。

 您的應用程式必須檢查呼叫可傳回 `error` 界面類型的函數或方法後是否發生錯誤。最基本的錯誤處理形式類似於下列範例：

```
if err != nil {
    // Handle error
    return
}
```

## 記錄錯誤
<a name="logging-errors"></a>

 最簡單的錯誤處理形式傳統上是在返回或退出應用程式之前記錄或列印錯誤訊息。

```
import "log"

// ...

if err != nil {
    log.Printf("error: %s", err.Error())
    return
}
```

## 服務用戶端錯誤
<a name="service-client-errors"></a>

 開發套件使用 [smithy.OperationError](https://pkg.go.dev/github.com/aws/smithy-go#OperationError) 錯誤類型包裝服務用戶端傳回的所有錯誤。 `OperationError`提供與基礎錯誤相關聯之服務名稱和操作的相關內容資訊。此資訊適用於透過集中式錯誤處理機制對一或多個 服務執行批次操作的應用程式。您的應用程式可以使用 `errors.As` 存取此`OperationError`中繼資料。

```
import "log"
import "github.com/aws/smithy-go"

// ...

if err != nil {
    var oe *smithy.OperationError
    if errors.As(err, &oe) {
        log.Printf("failed to call service: %s, operation: %s, error: %v", oe.Service(), oe.Operation(), oe.Unwrap())
    }
    return
}
```

### API 錯誤回應
<a name="api-error-responses"></a>

 服務操作可以傳回建模錯誤類型，以指出特定錯誤。這些建模類型可與 搭配使用`errors.As`，以取消包裝並判斷操作失敗是否是由於特定錯誤所致。例如，如果同名儲存貯體已存在，Amazon S3 `CreateBucket`可以傳回 [BucketAlreadyExists](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/s3/types#BucketAlreadyExists) 錯誤。

 例如，若要檢查錯誤是否為`BucketAlreadyExists`錯誤：

```
import "log"
import "github.com/aws/aws-sdk-go-v2/service/s3/types"

// ...

if err != nil {
    var bne *types.BucketAlreadyExists
    if errors.As(err, &bne) {
        log.Println("error:", bne)
    }
    return
}
```

 所有服務 API 回應錯誤都會實作 [smithy.APIError](https://pkg.go.dev/github.com/aws/smithy-go/#APIError) 介面類型。此界面可用於處理模型化或未模型化的服務錯誤回應。此類型可讓您存取 服務傳回的錯誤碼和訊息。此外，如果知道錯誤是否由用戶端或伺服器造成，此類型會提供指示。

```
import "log"
import "github.com/aws/smithy-go"

// ...

if err != nil {
    var ae smithy.APIError
    if errors.As(err, &ae) {
        log.Printf("code: %s, message: %s, fault: %s", ae.ErrorCode(), ae.ErrorMessage(), ae.ErrorFault().String())
    }
    return
}
```

## 擷取請求識別符
<a name="retrieving-request-identifiers"></a>

 使用 AWS Support 時，您可能需要提供請求識別符，以識別您嘗試故障診斷的請求。您可以使用 [http.ResponseError](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/aws/transport/http#ResponseError)，並使用 `ServiceRequestID()`方法擷取與錯誤回應相關聯的請求識別符。

```
import "log"
import awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http"

// ...

if err != nil {
    var re *awshttp.ResponseError
    if errors.As(err, &re) {
        log.Printf("requestID: %s, error: %v", re.ServiceRequestID(), re.Unwrap());
    }
    return
}
```

### Amazon S3 請求識別符
<a name="s3-request-identifiers"></a>

 Amazon S3 請求包含其他識別符，可用於協助 AWS Support 對您的請求進行故障診斷。您可以使用 [s3.ResponseError](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/s3#ResponseError) 和 呼叫 `ServiceRequestID()` 和 `ServiceHostID()`來擷取請求 ID 和主機 ID。

```
import "log"
import "github.com/aws/aws-sdk-go-v2/service/s3"

// ...

if err != nil {
    var re s3.ResponseError
    if errors.As(err, &re) {
        log.Printf("requestID: %s, hostID: %s request failure", re.ServiceRequestID(), re.ServiceHostID());
    }
    return
}
```