1package xml
2
3import (
4	"encoding/xml"
5	"fmt"
6	"io"
7)
8
9// ErrorComponents represents the error response fields
10// that will be deserialized from an xml error response body
11type ErrorComponents struct {
12	Code      string
13	Message   string
14	RequestID string
15}
16
17// GetErrorResponseComponents returns the error fields from an xml error response body
18func GetErrorResponseComponents(r io.Reader, noErrorWrapping bool) (ErrorComponents, error) {
19	if noErrorWrapping {
20		var errResponse noWrappedErrorResponse
21		if err := xml.NewDecoder(r).Decode(&errResponse); err != nil && err != io.EOF {
22			return ErrorComponents{}, fmt.Errorf("error while deserializing xml error response: %w", err)
23		}
24		return ErrorComponents{
25			Code:      errResponse.Code,
26			Message:   errResponse.Message,
27			RequestID: errResponse.RequestID,
28		}, nil
29	}
30
31	var errResponse wrappedErrorResponse
32	if err := xml.NewDecoder(r).Decode(&errResponse); err != nil && err != io.EOF {
33		return ErrorComponents{}, fmt.Errorf("error while deserializing xml error response: %w", err)
34	}
35	return ErrorComponents{
36		Code:      errResponse.Code,
37		Message:   errResponse.Message,
38		RequestID: errResponse.RequestID,
39	}, nil
40}
41
42// noWrappedErrorResponse represents the error response body with
43// no internal <Error></Error wrapping
44type noWrappedErrorResponse struct {
45	Code      string `xml:"Code"`
46	Message   string `xml:"Message"`
47	RequestID string `xml:"RequestId"`
48}
49
50// wrappedErrorResponse represents the error response body
51// wrapped within <Error>...</Error>
52type wrappedErrorResponse struct {
53	Code      string `xml:"Error>Code"`
54	Message   string `xml:"Error>Message"`
55	RequestID string `xml:"RequestId"`
56}
57