code.dwrz.net

Go monorepo.
Log | Files | Refs

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 }