1// Package awserr represents API error interface accessors for the SDK.
2package awserr
3
4// An Error wraps lower level errors with code, message and an original error.
5// The underlying concrete error type may also satisfy other interfaces which
6// can be to used to obtain more specific information about the error.
7//
8// Calling Error() or String() will always include the full information about
9// an error based on its underlying type.
10//
11// Example:
12//
13//     output, err := s3manage.Upload(svc, input, opts)
14//     if err != nil {
15//         if awsErr, ok := err.(awserr.Error); ok {
16//             // Get error details
17//             log.Println("Error:", awsErr.Code(), awsErr.Message())
18//
19//             // Prints out full error message, including original error if there was one.
20//             log.Println("Error:", awsErr.Error())
21//
22//             // Get original error
23//             if origErr := awsErr.OrigErr(); origErr != nil {
24//                 // operate on original error.
25//             }
26//         } else {
27//             fmt.Println(err.Error())
28//         }
29//     }
30//
31type Error interface {
32	// Satisfy the generic error interface.
33	error
34
35	// Returns the short phrase depicting the classification of the error.
36	Code() string
37
38	// Returns the error details message.
39	Message() string
40
41	// Returns the original error if one was set.  Nil is returned if not set.
42	OrigErr() error
43}
44
45// BatchError is a batch of errors which also wraps lower level errors with
46// code, message, and original errors. Calling Error() will include all errors
47// that occurred in the batch.
48//
49// Deprecated: Replaced with BatchedErrors. Only defined for backwards
50// compatibility.
51type BatchError interface {
52	// Satisfy the generic error interface.
53	error
54
55	// Returns the short phrase depicting the classification of the error.
56	Code() string
57
58	// Returns the error details message.
59	Message() string
60
61	// Returns the original error if one was set.  Nil is returned if not set.
62	OrigErrs() []error
63}
64
65// BatchedErrors is a batch of errors which also wraps lower level errors with
66// code, message, and original errors. Calling Error() will include all errors
67// that occurred in the batch.
68//
69// Replaces BatchError
70type BatchedErrors interface {
71	// Satisfy the base Error interface.
72	Error
73
74	// Returns the original error if one was set.  Nil is returned if not set.
75	OrigErrs() []error
76}
77
78// New returns an Error object described by the code, message, and origErr.
79//
80// If origErr satisfies the Error interface it will not be wrapped within a new
81// Error object and will instead be returned.
82func New(code, message string, origErr error) Error {
83	var errs []error
84	if origErr != nil {
85		errs = append(errs, origErr)
86	}
87	return newBaseError(code, message, errs)
88}
89
90// NewBatchError returns an BatchedErrors with a collection of errors as an
91// array of errors.
92func NewBatchError(code, message string, errs []error) BatchedErrors {
93	return newBaseError(code, message, errs)
94}
95
96// A RequestFailure is an interface to extract request failure information from
97// an Error such as the request ID of the failed request returned by a service.
98// RequestFailures may not always have a requestID value if the request failed
99// prior to reaching the service such as a connection error.
100//
101// Example:
102//
103//     output, err := s3manage.Upload(svc, input, opts)
104//     if err != nil {
105//         if reqerr, ok := err.(RequestFailure); ok {
106//             log.Println("Request failed", reqerr.Code(), reqerr.Message(), reqerr.RequestID())
107//         } else {
108//             log.Println("Error:", err.Error())
109//         }
110//     }
111//
112// Combined with awserr.Error:
113//
114//    output, err := s3manage.Upload(svc, input, opts)
115//    if err != nil {
116//        if awsErr, ok := err.(awserr.Error); ok {
117//            // Generic AWS Error with Code, Message, and original error (if any)
118//            fmt.Println(awsErr.Code(), awsErr.Message(), awsErr.OrigErr())
119//
120//            if reqErr, ok := err.(awserr.RequestFailure); ok {
121//                // A service error occurred
122//                fmt.Println(reqErr.StatusCode(), reqErr.RequestID())
123//            }
124//        } else {
125//            fmt.Println(err.Error())
126//        }
127//    }
128//
129type RequestFailure interface {
130	Error
131
132	// The status code of the HTTP response.
133	StatusCode() int
134
135	// The request ID returned by the service for a request failure. This will
136	// be empty if no request ID is available such as the request failed due
137	// to a connection error.
138	RequestID() string
139}
140
141// NewRequestFailure returns a wrapped error with additional information for
142// request status code, and service requestID.
143//
144// Should be used to wrap all request which involve service requests. Even if
145// the request failed without a service response, but had an HTTP status code
146// that may be meaningful.
147func NewRequestFailure(err Error, statusCode int, reqID string) RequestFailure {
148	return newRequestError(err, statusCode, reqID)
149}
150
151// UnmarshalError provides the interface for the SDK failing to unmarshal data.
152type UnmarshalError interface {
153	awsError
154	Bytes() []byte
155}
156
157// NewUnmarshalError returns an initialized UnmarshalError error wrapper adding
158// the bytes that fail to unmarshal to the error.
159func NewUnmarshalError(err error, msg string, bytes []byte) UnmarshalError {
160	return &unmarshalError{
161		awsError: New("UnmarshalError", msg, err),
162		bytes:    bytes,
163	}
164}
165