1package customizations_test 2 3import ( 4 "context" 5 "errors" 6 "net/http" 7 "net/http/httptest" 8 "strings" 9 "testing" 10 11 "github.com/aws/aws-sdk-go-v2/aws" 12 "github.com/aws/aws-sdk-go-v2/service/route53" 13 "github.com/aws/aws-sdk-go-v2/service/route53/types" 14) 15 16func TestCustomErrorDeserialization(t *testing.T) { 17 cases := map[string]struct { 18 responseStatus int 19 responseBody []byte 20 expectedError string 21 expectedRequestID string 22 expectedResponseID string 23 }{ 24 "invalidChangeBatchError": { 25 responseStatus: 500, 26 responseBody: []byte(`<?xml version="1.0" encoding="UTF-8"?> 27 <InvalidChangeBatch xmlns="https://route53.amazonaws.com/doc/2013-04-01/"> 28 <Messages> 29 <Message>Tried to create resource record set duplicate.example.com. type A, but it already exists</Message> 30 </Messages> 31 <RequestId>b25f48e8-84fd-11e6-80d9-574e0c4664cb</RequestId> 32 </InvalidChangeBatch>`), 33 expectedError: "InvalidChangeBatch: ChangeBatch errors occurred", 34 expectedRequestID: "b25f48e8-84fd-11e6-80d9-574e0c4664cb", 35 }, 36 37 "standardRestXMLError": { 38 responseStatus: 500, 39 responseBody: []byte(`<?xml version="1.0"?> 40 <ErrorResponse xmlns="http://route53.amazonaws.com/doc/2016-09-07/"> 41 <Error> 42 <Type>Sender</Type> 43 <Code>MalformedXML</Code> 44 <Message>1 validation error detected: Value null at 'route53#ChangeSet' failed to satisfy constraint: Member must not be null</Message> 45 </Error> 46 <RequestId>b25f48e8-84fd-11e6-80d9-574e0c4664cb</RequestId> 47 </ErrorResponse> 48 `), 49 expectedError: "1 validation error detected:", 50 expectedRequestID: "b25f48e8-84fd-11e6-80d9-574e0c4664cb", 51 }, 52 53 "Success response": { 54 responseStatus: 200, 55 responseBody: []byte(`<?xml version="1.0" encoding="UTF-8"?> 56 <ChangeResourceRecordSetsResponse> 57 <ChangeInfo> 58 <Comment>mockComment</Comment> 59 <Id>mockID</Id> 60 </ChangeInfo> 61 </ChangeResourceRecordSetsResponse>`), 62 expectedResponseID: "mockID", 63 }, 64 } 65 66 for name, c := range cases { 67 server := httptest.NewServer(http.HandlerFunc( 68 func(w http.ResponseWriter, r *http.Request) { 69 w.WriteHeader(c.responseStatus) 70 w.Write(c.responseBody) 71 })) 72 defer server.Close() 73 74 t.Run(name, func(t *testing.T) { 75 svc := route53.NewFromConfig(aws.Config{ 76 Region: "us-east-1", 77 EndpointResolver: aws.EndpointResolverFunc(func(service, region string) (aws.Endpoint, error) { 78 return aws.Endpoint{ 79 URL: server.URL, 80 SigningName: "route53", 81 }, nil 82 }), 83 Retryer: func() aws.Retryer { 84 return aws.NopRetryer{} 85 }, 86 }) 87 resp, err := svc.ChangeResourceRecordSets(context.Background(), &route53.ChangeResourceRecordSetsInput{ 88 ChangeBatch: &types.ChangeBatch{ 89 Changes: []types.Change{}, 90 Comment: aws.String("mock"), 91 }, 92 HostedZoneId: aws.String("zone"), 93 }) 94 95 if err == nil && len(c.expectedError) != 0 { 96 t.Fatalf("expected err, got none") 97 } 98 99 if len(c.expectedError) != 0 { 100 if e, a := c.expectedError, err.Error(); !strings.Contains(a, e) { 101 t.Fatalf("expected error to be %s, got %s", e, a) 102 } 103 104 var responseError interface { 105 ServiceRequestID() string 106 } 107 108 if !errors.As(err, &responseError) { 109 t.Fatalf("expected error to be of type %T, was not", responseError) 110 } 111 112 if e, a := c.expectedRequestID, responseError.ServiceRequestID(); !strings.EqualFold(e, a) { 113 t.Fatalf("expected request id to be %s, got %s", e, a) 114 } 115 } 116 117 if len(c.expectedResponseID) != 0 { 118 if e, a := c.expectedResponseID, *resp.ChangeInfo.Id; !strings.EqualFold(e, a) { 119 t.Fatalf("expected response to have id %v, got %v", e, a) 120 } 121 } 122 123 }) 124 } 125} 126