1package protocol
2
3import (
4	"net/http"
5
6	"github.com/aws/aws-sdk-go/aws/awserr"
7	"github.com/aws/aws-sdk-go/aws/request"
8)
9
10// UnmarshalErrorHandler provides unmarshaling errors API response errors for
11// both typed and untyped errors.
12type UnmarshalErrorHandler struct {
13	unmarshaler ErrorUnmarshaler
14}
15
16// ErrorUnmarshaler is an abstract interface for concrete implementations to
17// unmarshal protocol specific response errors.
18type ErrorUnmarshaler interface {
19	UnmarshalError(*http.Response, ResponseMetadata) (error, error)
20}
21
22// NewUnmarshalErrorHandler returns an UnmarshalErrorHandler
23// initialized for the set of exception names to the error unmarshalers
24func NewUnmarshalErrorHandler(unmarshaler ErrorUnmarshaler) *UnmarshalErrorHandler {
25	return &UnmarshalErrorHandler{
26		unmarshaler: unmarshaler,
27	}
28}
29
30// UnmarshalErrorHandlerName is the name of the named handler.
31const UnmarshalErrorHandlerName = "awssdk.protocol.UnmarshalError"
32
33// NamedHandler returns a NamedHandler for the unmarshaler using the set of
34// errors the unmarshaler was initialized for.
35func (u *UnmarshalErrorHandler) NamedHandler() request.NamedHandler {
36	return request.NamedHandler{
37		Name: UnmarshalErrorHandlerName,
38		Fn:   u.UnmarshalError,
39	}
40}
41
42// UnmarshalError will attempt to unmarshal the API response's error message
43// into either a generic SDK error type, or a typed error corresponding to the
44// errors exception name.
45func (u *UnmarshalErrorHandler) UnmarshalError(r *request.Request) {
46	defer r.HTTPResponse.Body.Close()
47
48	respMeta := ResponseMetadata{
49		StatusCode: r.HTTPResponse.StatusCode,
50		RequestID:  r.RequestID,
51	}
52
53	v, err := u.unmarshaler.UnmarshalError(r.HTTPResponse, respMeta)
54	if err != nil {
55		r.Error = awserr.NewRequestFailure(
56			awserr.New(request.ErrCodeSerialization,
57				"failed to unmarshal response error", err),
58			respMeta.StatusCode,
59			respMeta.RequestID,
60		)
61		return
62	}
63
64	r.Error = v
65}
66