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