1package customizations 2 3import ( 4 "bytes" 5 "context" 6 "encoding/xml" 7 "fmt" 8 "io" 9 "io/ioutil" 10 "strings" 11 12 "github.com/aws/smithy-go" 13 smithyxml "github.com/aws/smithy-go/encoding/xml" 14 "github.com/aws/smithy-go/middleware" 15 "github.com/aws/smithy-go/ptr" 16 smithyhttp "github.com/aws/smithy-go/transport/http" 17 18 awsmiddle "github.com/aws/aws-sdk-go-v2/aws/middleware" 19 "github.com/aws/aws-sdk-go-v2/service/route53/types" 20) 21 22// HandleCustomErrorDeserialization check if Route53 response is an error and needs 23// custom error deserialization. 24// 25func HandleCustomErrorDeserialization(stack *middleware.Stack) error { 26 return stack.Deserialize.Insert(&processResponse{}, "OperationDeserializer", middleware.After) 27} 28 29// middleware to process raw response and look for error response with InvalidChangeBatch error tag 30type processResponse struct{} 31 32// ID returns the middleware ID. 33func (*processResponse) ID() string { 34 return "Route53:ProcessResponseForCustomErrorResponse" 35} 36 37func (m *processResponse) HandleDeserialize( 38 ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( 39 out middleware.DeserializeOutput, metadata middleware.Metadata, err error, 40) { 41 out, metadata, err = next.HandleDeserialize(ctx, in) 42 if err != nil { 43 return out, metadata, err 44 } 45 46 response, ok := out.RawResponse.(*smithyhttp.Response) 47 if !ok { 48 return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} 49 } 50 51 // check if success response 52 if response.StatusCode >= 200 && response.StatusCode < 300 { 53 return 54 } 55 56 var readBuff bytes.Buffer 57 body := io.TeeReader(response.Body, &readBuff) 58 59 rootDecoder := xml.NewDecoder(body) 60 t, err := smithyxml.FetchRootElement(rootDecoder) 61 if err == io.EOF { 62 return out, metadata, nil 63 } 64 65 // rewind response body 66 response.Body = ioutil.NopCloser(io.MultiReader(&readBuff, response.Body)) 67 68 // if start tag is "InvalidChangeBatch", the error response needs custom unmarshaling. 69 if strings.EqualFold(t.Name.Local, "InvalidChangeBatch") { 70 return out, metadata, route53CustomErrorDeser(&metadata, response) 71 } 72 73 return out, metadata, err 74} 75 76// error type for invalidChangeBatchError 77type invalidChangeBatchError struct { 78 Messages []string `xml:"Messages>Message"` 79 RequestID string `xml:"RequestId"` 80} 81 82func route53CustomErrorDeser(metadata *middleware.Metadata, response *smithyhttp.Response) error { 83 err := invalidChangeBatchError{} 84 xml.NewDecoder(response.Body).Decode(&err) 85 86 // set request id in metadata 87 if len(err.RequestID) != 0 { 88 awsmiddle.SetRequestIDMetadata(metadata, err.RequestID) 89 } 90 91 return &types.InvalidChangeBatch{ 92 Message: ptr.String("ChangeBatch errors occurred"), 93 Messages: err.Messages, 94 } 95} 96