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