1 /*
2  * Copyright 2010-2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */

15 package com.amazonaws;
16
17 import com.amazonaws.util.StringUtils;
18
19 import java.util.Map;
20
21 /**
22  * Extension of SdkClientException that represents an error response returned
23  * by an Amazon web service. Receiving an exception of this type indicates that
24  * the caller's request was correctly transmitted to the service, but for some
25  * reason, the service was not able to process it, and returned an error
26  * response instead.
27  * <p>
28  * AmazonServiceException provides callers several pieces of
29  * information that can be used to obtain more information about the error and
30  * why it occurred. In particular, the errorType field can be used to determine
31  * if the caller's request was invalid, or the service encountered an error on
32  * the server side while processing it.
33  */

34 public class AmazonServiceException extends SdkClientException {
35     private static final long serialVersionUID = 1L;
36
37     /**
38      * Indicates who is responsible (if known) for a failed request.
39      *
40      * <p>For example, if a client is using an invalid AWS access key,
41      * the returned exception will indicate that there is an error in the
42      * request the caller is sending. Retrying that same request will *not*
43      * result in a successful response. The Client ErrorType indicates that
44      * there is a problem in the request the user is sending (ex: incorrect
45      * access keys, invalid parameter value, missing parameter, etc.), and that
46      * the caller must take some action to correct the request before it should
47      * be resent. Client errors are typically associated an HTTP error code in
48      * the 4xx range.
49      *
50      * <p>The Service ErrorType indicates that although the request the
51      * caller sent was valid, the service was unable to fulfill the request
52      * because of problems on the service's side. These types of errors can be
53      * retried by the caller since the caller's request was valid and the
54      * problem occurred while processing the request on the service side.
55      * Service errors will be accompanied by an HTTP error code in the 5xx
56      * range.
57      *
58      * <p>Finally, if there isn't enough information to determine who's
59      * fault the error response is, an Unknown ErrorType will be set.
60      */

61     public enum ErrorType {
62         Client,
63         Service,
64         Unknown
65     }
66
67     /**
68      * The unique AWS identifier for the service request the caller made. The
69      * AWS request ID can uniquely identify the AWS request, and is used for
70      * reporting an error to AWS support team.
71      */

72     private String requestId;
73
74     /**
75      * The AWS error code represented by this exception (ex:
76      * InvalidParameterValue).
77      */

78     private String errorCode;
79
80     /**
81      * Indicates (if known) whether this exception was the fault of the caller
82      * or the service.
83      *
84      * @see ErrorType
85      */

86     private ErrorType errorType = ErrorType.Unknown;
87
88     /**
89      * The error message as returned by the service.
90      */

91     private String errorMessage;
92
93     /** The HTTP status code that was returned with this error */
94     private int statusCode;
95
96     /**
97      * The name of the Amazon service that sent this error response.
98      */

99     private String serviceName;
100
101     /**
102      * All HTTP headers in the response for additional context and debugging.
103      */

104     private Map<String, String> httpHeaders;
105
106     /**
107      * The raw response payload.
108      */

109     private byte[] rawResponse;
110
111     /**
112      * Track proxy host if configured, in case error response came from proxy instead of AWS.
113      */

114     private String proxyHost;
115
116     /**
117      * Constructs a new AmazonServiceException with the specified message.
118      *
119      * @param errorMessage
120      *            An error message describing what went wrong.
121      */

122     public AmazonServiceException(String errorMessage) {
123         super((String)null);
124         this.errorMessage = errorMessage;
125     }
126
127     /**
128      * Constructs a new AmazonServiceException with the specified message and
129      * exception indicating the root cause.
130      *
131      * @param errorMessage
132      *            An error message describing what went wrong.
133      * @param cause
134      *            The root exception that caused this exception to be thrown.
135      */

136     public AmazonServiceException(String errorMessage, Exception cause) {
137         super(null, cause);
138         this.errorMessage = errorMessage;
139     }
140
141     /**
142      * Sets the AWS requestId for this exception.
143      *
144      * @param requestId
145      *            The unique identifier for the service request the caller made.
146      */

147     public void setRequestId(String requestId) {
148         this.requestId = requestId;
149     }
150
151     /**
152      * Returns the AWS request ID that uniquely identifies the service request
153      * the caller made.
154      *
155      * @return The AWS request ID that uniquely identifies the service request
156      *         the caller made.
157      */

158     public String getRequestId() {
159         return requestId;
160     }
161
162     /**
163      * Sets the name of the service that sent this error response.
164      *
165      * @param serviceName
166      *            The name of the service that sent this error response.
167      */

168     public void setServiceName(String serviceName) {
169         this.serviceName = serviceName;
170     }
171
172     /**
173      * Returns the name of the service that sent this error response.
174      *
175      * @return The name of the service that sent this error response.
176      */

177     public String getServiceName() {
178         return serviceName;
179     }
180
181     /**
182      * Sets the AWS error code represented by this exception.
183      *
184      * @param errorCode
185      *            The AWS error code represented by this exception.
186      */

187     public void setErrorCode(String errorCode) {
188         this.errorCode = errorCode;
189     }
190
191     /**
192      * Returns the AWS error code represented by this exception.
193      *
194      * @return The AWS error code represented by this exception.
195      */

196     public String getErrorCode() {
197         return errorCode;
198     }
199
200     /**
201      * Sets the type of error represented by this exception (sender, receiver,
202      * or unknown), indicating if this exception was the caller's fault, or the
203      * service's fault.
204      *
205      * @param errorType
206      *            The type of error represented by this exception (sender or
207      *            receiver), indicating if this exception was the caller's fault
208      *            or the service's fault.
209      */

210     public void setErrorType(ErrorType errorType) {
211         this.errorType = errorType;
212     }
213
214     /**
215      * Indicates who is responsible for this exception (caller, service,
216      * or unknown).
217      *
218      * @return A value indicating who is responsible for this exception (caller, service, or unknown).
219      */

220     public ErrorType getErrorType() {
221         return errorType;
222     }
223
224     /**
225      * @return the human-readable error message provided by the service
226      */

227     public String getErrorMessage() {
228         return errorMessage;
229     }
230
231     /**
232      * Sets the human-readable error message provided by the service.
233      *
234      * NOTE: errorMessage by default is set to the same as the message value
235      * passed to the constructor of AmazonServiceException.
236      *
237      * @see AmazonServiceException#AmazonServiceException(String)
238      * @see AmazonServiceException#AmazonServiceException(String, Exception))
239      */

240     public void setErrorMessage(String value) {
241         errorMessage = value;
242     }
243
244     /**
245      * Sets the HTTP status code that was returned with this service exception.
246      *
247      * @param statusCode
248      *            The HTTP status code that was returned with this service
249      *            exception.
250      */

251     public void setStatusCode(int statusCode) {
252         this.statusCode = statusCode;
253     }
254
255     /**
256      * Returns the HTTP status code that was returned with this service
257      * exception.
258      *
259      * @return The HTTP status code that was returned with this service
260      *         exception.
261      */

262     public int getStatusCode() {
263         return statusCode;
264     }
265
266     @Override
267     public String getMessage() {
268         return getErrorMessage()
269             + " (Service: " + getServiceName()
270             + "; Status Code: " + getStatusCode()
271             + "; Error Code: " + getErrorCode()
272             + "; Request ID: " + getRequestId()
273             + "; Proxy: " + getProxyHost()
274             + ")";
275     }
276
277     /**
278      * Typically only useful for debugging purpose if for some reason the SDK cannot parse the HTTP
279      * response from a service
280      *
281      * @return The raw content of the HTTP response as a String.
282      */

283     public String getRawResponseContent() {
284         return rawResponse == null ? null : new String(rawResponse, StringUtils.UTF8);
285     }
286
287     /**
288      * Sets the raw response content.
289      */

290     public void setRawResponseContent(String rawResponseContent) {
291         this.rawResponse = rawResponseContent == null ? null : rawResponseContent.getBytes
292                 (StringUtils.UTF8);
293     }
294
295     /**
296      * Returns the response payload as bytes.
297      */

298     public byte[] getRawResponse() {
299         return rawResponse == null ? null : rawResponse.clone();
300     }
301
302     /**
303      * Sets the raw response content.
304      */

305     public void setRawResponse(byte[] rawResponse) {
306         this.rawResponse = rawResponse == null ? null : rawResponse.clone();
307     }
308
309     /**
310      * @return A Map of HTTP headers associated with the error response.
311      */

312     public Map<String, String> getHttpHeaders() {
313         return httpHeaders;
314     }
315
316     /**
317      * Sets the headers present in the error response.
318      */

319     public void setHttpHeaders(Map<String, String> httpHeaders) {
320         this.httpHeaders = httpHeaders;
321     }
322
323     /**
324      * Returns proxy host if configured.
325      * If using a proxy, then it's possible that the error response came from the proxy instead of AWS.
326      *
327      * @return proxy host if configured or {@code null}
328      */

329     public String getProxyHost() {
330         return proxyHost;
331     }
332
333     /**
334      * Sets proxy host.
335      *
336      * @param proxyHost the proxy host to set
337      */

338     public void setProxyHost(String proxyHost) {
339         this.proxyHost = proxyHost;
340     }
341 }
342