github.com/aavshr/aws-sdk-go@v1.41.3/example/aws/request/customRetryer/custom_retryer.go (about)

     1  //go:build example
     2  // +build example
     3  
     4  package main
     5  
     6  import (
     7  	"fmt"
     8  
     9  	"github.com/aavshr/aws-sdk-go/aws"
    10  	"github.com/aavshr/aws-sdk-go/aws/awserr"
    11  	"github.com/aavshr/aws-sdk-go/aws/client"
    12  	"github.com/aavshr/aws-sdk-go/aws/credentials"
    13  	"github.com/aavshr/aws-sdk-go/aws/defaults"
    14  	"github.com/aavshr/aws-sdk-go/aws/endpoints"
    15  	"github.com/aavshr/aws-sdk-go/aws/request"
    16  	"github.com/aavshr/aws-sdk-go/aws/session"
    17  	"github.com/aavshr/aws-sdk-go/service/cloudwatchlogs"
    18  )
    19  
    20  func main() {
    21  	sess := session.Must(
    22  		session.NewSession(&aws.Config{
    23  			// Use a custom retryer to provide custom retry rules.
    24  			Retryer: CustomRetryer{
    25  				DefaultRetryer: client.DefaultRetryer{
    26  					NumMaxRetries: client.DefaultRetryerMaxNumRetries,
    27  				}},
    28  
    29  			// Use the SDK's SharedCredentialsProvider directly instead of the
    30  			// SDK's default credential chain. This ensures that the
    31  			// application can call Config.Credentials.Expire. This  is counter
    32  			// to the SDK's default credentials chain, which  will never reread
    33  			// the shared credentials file.
    34  			Credentials: credentials.NewCredentials(&credentials.SharedCredentialsProvider{
    35  				Filename: defaults.SharedCredentialsFilename(),
    36  				Profile:  "default",
    37  			}),
    38  			Region: aws.String(endpoints.UsWest2RegionID),
    39  		}),
    40  	)
    41  	// Add a request handler to the AfterRetry handler stack that is used by the
    42  	// SDK to be executed after the SDK has determined if it will retry.
    43  	// This handler forces the SDK's Credentials to be expired, and next call to
    44  	// Credentials.Get will attempt to refresh the credentials.
    45  	sess.Handlers.AfterRetry.PushBack(func(req *request.Request) {
    46  		if aerr, ok := req.Error.(awserr.RequestFailure); ok && aerr != nil {
    47  			if aerr.Code() == "InvalidClaimException" {
    48  				// Force the credentials to expire based on error code.  Next
    49  				// call to Credentials.Get will attempt to refresh credentials.
    50  				req.Config.Credentials.Expire()
    51  			}
    52  		}
    53  	})
    54  
    55  	svc := cloudwatchlogs.New(sess)
    56  
    57  	resp, err := svc.DescribeLogGroups(&cloudwatchlogs.DescribeLogGroupsInput{})
    58  
    59  	fmt.Println(resp, err)
    60  }
    61  
    62  // CustomRetryer wraps the SDK's built in DefaultRetryer adding additional
    63  // custom features. Such as, no retry for 5xx status codes, and refresh
    64  // credentials.
    65  type CustomRetryer struct {
    66  	client.DefaultRetryer
    67  }
    68  
    69  // ShouldRetry overrides the SDK's built in DefaultRetryer adding customization
    70  // to not retry 5xx status codes.
    71  func (r CustomRetryer) ShouldRetry(req *request.Request) bool {
    72  	if req.HTTPResponse.StatusCode >= 500 {
    73  		// Don't retry any 5xx status codes.
    74  		return false
    75  	}
    76  
    77  	// Fallback to SDK's built in retry rules
    78  	return r.DefaultRetryer.ShouldRetry(req)
    79  }