1//go:build example 2// +build example 3 4package main 5 6import ( 7 "fmt" 8 9 "github.com/aws/aws-sdk-go/aws" 10 "github.com/aws/aws-sdk-go/aws/awserr" 11 "github.com/aws/aws-sdk-go/aws/client" 12 "github.com/aws/aws-sdk-go/aws/credentials" 13 "github.com/aws/aws-sdk-go/aws/defaults" 14 "github.com/aws/aws-sdk-go/aws/endpoints" 15 "github.com/aws/aws-sdk-go/aws/request" 16 "github.com/aws/aws-sdk-go/aws/session" 17 "github.com/aws/aws-sdk-go/service/cloudwatchlogs" 18) 19 20func 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. 65type 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. 71func (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} 80