Skip to content

Commit 47b8546

Browse files
authored
Merge pull request #10 from IBM/error-debug-info
Add additional error information
2 parents 37f3efe + 1c6bf26 commit 47b8546

13 files changed

+159
-104
lines changed

src/main/java/com/ibm/cloud/sdk/core/service/WatsonService.java

Lines changed: 12 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
*/
1313
package com.ibm.cloud.sdk.core.service;
1414

15-
import com.google.gson.JsonObject;
1615
import com.ibm.cloud.sdk.core.http.HttpClientSingleton;
1716
import com.ibm.cloud.sdk.core.http.HttpConfigOptions;
1817
import com.ibm.cloud.sdk.core.http.HttpHeaders;
@@ -39,8 +38,6 @@
3938
import com.ibm.cloud.sdk.core.util.CredentialUtils;
4039
import com.ibm.cloud.sdk.core.util.RequestUtils;
4140
import com.ibm.cloud.sdk.core.util.ResponseConverterUtils;
42-
import com.ibm.cloud.sdk.core.util.ResponseUtils;
43-
4441
import jersey.repackaged.jsr166e.CompletableFuture;
4542
import okhttp3.Call;
4643
import okhttp3.Callback;
@@ -54,7 +51,6 @@
5451

5552
import java.io.IOException;
5653
import java.util.Map;
57-
import java.util.logging.Level;
5854
import java.util.logging.Logger;
5955
import java.util.regex.Pattern;
6056

@@ -68,8 +64,6 @@ public abstract class WatsonService {
6864
private static final String URL = "url";
6965
private static final String PATH_AUTHORIZATION_V1_TOKEN = "/v1/token";
7066
private static final String AUTHORIZATION = "authorization";
71-
private static final String MESSAGE_ERROR_3 = "message";
72-
private static final String MESSAGE_ERROR_2 = "error_message";
7367
private static final String BASIC = "Basic ";
7468
private static final String BEARER = "Bearer ";
7569
private static final String APIKEY_AS_USERNAME = "apikey";
@@ -98,8 +92,6 @@ public abstract class WatsonService {
9892
/** The Constant MESSAGE_CODE. */
9993
protected static final String MESSAGE_CODE = "code";
10094

101-
/** The Constant MESSAGE_ERROR. */
102-
protected static final String MESSAGE_ERROR = "error";
10395

10496
/** The Constant VERSION. */
10597
protected static final String VERSION = "version";
@@ -308,38 +300,6 @@ public boolean isTokenManagerSet() {
308300
return tokenManager != null;
309301
}
310302

311-
/**
312-
* Gets the error message from a JSON response.
313-
*
314-
* <pre>
315-
* {
316-
* code: 400
317-
* error: 'bad request'
318-
* }
319-
* </pre>
320-
*
321-
* @param response the HTTP response
322-
* @return the error message from the JSON object
323-
*/
324-
private String getErrorMessage(Response response) {
325-
String error = ResponseUtils.getString(response);
326-
try {
327-
328-
final JsonObject jsonObject = ResponseUtils.getJsonObject(error);
329-
if (jsonObject.has(MESSAGE_ERROR)) {
330-
error = jsonObject.get(MESSAGE_ERROR).getAsString();
331-
} else if (jsonObject.has(MESSAGE_ERROR_2)) {
332-
error = jsonObject.get(MESSAGE_ERROR_2).getAsString();
333-
} else if (jsonObject.has(MESSAGE_ERROR_3)) {
334-
error = jsonObject.get(MESSAGE_ERROR_3).getAsString();
335-
}
336-
} catch (final Exception e) {
337-
// Ignore any kind of exception parsing the json and use fallback String version of response
338-
}
339-
340-
return error;
341-
}
342-
343303
/**
344304
* Gets the name.
345305
*
@@ -494,39 +454,31 @@ protected <T> T processServiceCall(final ResponseConverter<T> converter, final R
494454
return converter.convert(response);
495455
}
496456

497-
// There was a Client Error 4xx or a Server Error 5xx
498-
// Get the error message and create the exception
499-
final String error = getErrorMessage(response);
500-
LOG.log(Level.SEVERE, response.request().method() + " " + response.request().url().toString() + ", status: "
501-
+ response.code() + ", error: " + error);
502-
503457
switch (response.code()) {
504458
case HttpStatus.BAD_REQUEST: // HTTP 400
505-
throw new BadRequestException(error != null ? error : "Bad Request", response);
459+
throw new BadRequestException(response);
506460
case HttpStatus.UNAUTHORIZED: // HTTP 401
507-
throw new UnauthorizedException("Unauthorized: Access is denied due to invalid credentials. "
508-
+ "Tip: Did you set the Endpoint?", response);
461+
throw new UnauthorizedException(response);
509462
case HttpStatus.FORBIDDEN: // HTTP 403
510-
throw new ForbiddenException(error != null ? error : "Forbidden: Service refuse the request", response);
463+
throw new ForbiddenException(response);
511464
case HttpStatus.NOT_FOUND: // HTTP 404
512-
throw new NotFoundException(error != null ? error : "Not found", response);
465+
throw new NotFoundException(response);
513466
case HttpStatus.NOT_ACCEPTABLE: // HTTP 406
514-
throw new ForbiddenException(error != null ? error : "Forbidden: Service refuse the request", response);
467+
throw new ForbiddenException(response);
515468
case HttpStatus.CONFLICT: // HTTP 409
516-
throw new ConflictException(error != null ? error : "", response);
469+
throw new ConflictException(response);
517470
case HttpStatus.REQUEST_TOO_LONG: // HTTP 413
518-
throw new RequestTooLargeException(error != null ? error
519-
: "Request too large: " + "The request entity is larger than the server is able to process", response);
471+
throw new RequestTooLargeException(response);
520472
case HttpStatus.UNSUPPORTED_MEDIA_TYPE: // HTTP 415
521-
throw new UnsupportedException(error != null ? error : "Unsupported Media Type", response);
473+
throw new UnsupportedException(response);
522474
case HttpStatus.TOO_MANY_REQUESTS: // HTTP 429
523-
throw new TooManyRequestsException(error != null ? error : "Too many requests", response);
475+
throw new TooManyRequestsException(response);
524476
case HttpStatus.INTERNAL_SERVER_ERROR: // HTTP 500
525-
throw new InternalServerErrorException(error != null ? error : "Internal Server Error", response);
477+
throw new InternalServerErrorException(response);
526478
case HttpStatus.SERVICE_UNAVAILABLE: // HTTP 503
527-
throw new ServiceUnavailableException(error != null ? error : "Service Unavailable", response);
479+
throw new ServiceUnavailableException(response);
528480
default: // other errors
529-
throw new ServiceResponseException(response.code(), error, response);
481+
throw new ServiceResponseException(response.code(), response);
530482
}
531483
}
532484

src/main/java/com/ibm/cloud/sdk/core/service/exception/BadRequestException.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@ public class BadRequestException extends ServiceResponseException {
2727
/**
2828
* Instantiates a new BadRequest Exception. HTTP 400
2929
*
30-
* @param message the error message
3130
* @param response the HTTP response
3231
*/
33-
public BadRequestException(String message, Response response) {
34-
super(HttpStatus.BAD_REQUEST, message, response);
32+
public BadRequestException(Response response) {
33+
super(HttpStatus.BAD_REQUEST, response);
34+
if (this.getMessage() == null) {
35+
this.setMessage("Bad request");
36+
}
3537
}
3638

3739
}

src/main/java/com/ibm/cloud/sdk/core/service/exception/ConflictException.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ public class ConflictException extends ServiceResponseException {
2929
/**
3030
* Instantiates a new Forbidden Exception.
3131
*
32-
* @param message the error message
3332
* @param response the HTTP response
3433
*/
35-
public ConflictException(String message, Response response) {
36-
super(HttpStatus.CONFLICT, message, response);
34+
public ConflictException(Response response) {
35+
super(HttpStatus.CONFLICT, response);
36+
if (this.getMessage() == null) {
37+
this.setMessage("");
38+
}
3739
}
3840

3941
}

src/main/java/com/ibm/cloud/sdk/core/service/exception/ForbiddenException.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ public class ForbiddenException extends ServiceResponseException {
2929
/**
3030
* Instantiates a new Forbidden Exception.
3131
*
32-
* @param message the error message
3332
* @param response the HTTP response
3433
*/
35-
public ForbiddenException(String message, Response response) {
36-
super(HttpStatus.FORBIDDEN, message, response);
34+
public ForbiddenException(Response response) {
35+
super(HttpStatus.FORBIDDEN, response);
36+
if (this.getMessage() == null) {
37+
this.setMessage("Forbidden: Service refused the request");
38+
}
3739
}
3840

3941
}

src/main/java/com/ibm/cloud/sdk/core/service/exception/InternalServerErrorException.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ public class InternalServerErrorException extends ServiceResponseException {
2929
/**
3030
* Instantiates a new Internal Server Error Exception.
3131
*
32-
* @param message the error message
3332
* @param response the HTTP response
3433
*/
35-
public InternalServerErrorException(String message, Response response) {
36-
super(HttpStatus.INTERNAL_SERVER_ERROR, message, response);
34+
public InternalServerErrorException(Response response) {
35+
super(HttpStatus.INTERNAL_SERVER_ERROR, response);
36+
if (this.getMessage() == null) {
37+
this.setMessage("Internal server error");
38+
}
3739
}
3840

3941
}

src/main/java/com/ibm/cloud/sdk/core/service/exception/NotFoundException.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ public class NotFoundException extends ServiceResponseException {
2929
/**
3030
* Instantiates a new not found exception.
3131
*
32-
* @param message the message
3332
* @param response the HTTP response
3433
*/
35-
public NotFoundException(String message, Response response) {
36-
super(HttpStatus.NOT_FOUND, message, response);
34+
public NotFoundException(Response response) {
35+
super(HttpStatus.NOT_FOUND, response);
36+
if (this.getMessage() == null) {
37+
this.setMessage("Not found");
38+
}
3739
}
3840

3941
}

src/main/java/com/ibm/cloud/sdk/core/service/exception/RequestTooLargeException.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ public class RequestTooLargeException extends ServiceResponseException {
2929
/**
3030
* Instantiates a new Request Too Large Exception.
3131
*
32-
* @param message the error message
3332
* @param response the HTTP response
3433
*/
35-
public RequestTooLargeException(String message, Response response) {
36-
super(HttpStatus.REQUEST_TOO_LONG, message, response);
34+
public RequestTooLargeException(Response response) {
35+
super(HttpStatus.REQUEST_TOO_LONG, response);
36+
if (this.getMessage() == null) {
37+
this.setMessage("Request too large: The request entity is larger than the server is able to process");
38+
}
3739
}
3840

3941
}

src/main/java/com/ibm/cloud/sdk/core/service/exception/ServiceResponseException.java

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,16 @@
1212
*/
1313
package com.ibm.cloud.sdk.core.service.exception;
1414

15+
import com.google.gson.JsonObject;
16+
import com.google.gson.reflect.TypeToken;
17+
import com.ibm.cloud.sdk.core.http.Headers;
18+
import com.ibm.cloud.sdk.core.util.GsonSingleton;
19+
import com.ibm.cloud.sdk.core.util.ResponseUtils;
1520
import okhttp3.Response;
1621

22+
import java.lang.reflect.Type;
23+
import java.util.Map;
24+
1725
/**
1826
* Generic Service Response Exception.
1927
*/
@@ -22,23 +30,46 @@ public class ServiceResponseException extends RuntimeException {
2230
/** The Constant serialVersionUID. */
2331
private static final long serialVersionUID = 1L;
2432

33+
/** Potential error message keys. */
34+
private static final String MESSAGE_ERROR = "error";
35+
private static final String MESSAGE_ERROR_2 = "error_message";
36+
private static final String MESSAGE_ERROR_3 = "message";
37+
private static final String[] ERROR_KEYS = { MESSAGE_ERROR, MESSAGE_ERROR_2, MESSAGE_ERROR_3 };
38+
39+
private static final Type debuggingInfoType = new TypeToken<Map<String, Object>>() { }.getType();
40+
2541
/** The status code. */
2642
private final int statusCode;
2743

28-
/** The HTTP response. */
29-
private final Response response;
44+
private String message;
45+
private Headers headers;
46+
private Map<String, Object> debuggingInfo;
3047

3148
/**
3249
* Instantiates a new Service Response Exception.
3350
*
3451
* @param statusCode the status code
35-
* @param message the error message
3652
* @param response the HTTP response
3753
*/
38-
public ServiceResponseException(int statusCode, String message, Response response) {
39-
super(message);
54+
public ServiceResponseException(int statusCode, Response response) {
55+
super();
4056
this.statusCode = statusCode;
41-
this.response = response;
57+
this.headers = new Headers(response.headers());
58+
59+
String responseString = ResponseUtils.getString(response);
60+
try {
61+
final JsonObject jsonObject = ResponseUtils.getJsonObject(responseString);
62+
for (String errorKey : ERROR_KEYS) {
63+
if (jsonObject.has(errorKey)) {
64+
this.message = jsonObject.remove(errorKey).getAsString();
65+
break;
66+
}
67+
}
68+
this.debuggingInfo = GsonSingleton.getGson().fromJson(jsonObject, debuggingInfoType);
69+
} catch (final Exception e) {
70+
// Ignore any kind of exception parsing the json and use fallback String version of response
71+
this.message = responseString;
72+
}
4273
}
4374

4475
/**
@@ -51,11 +82,38 @@ public int getStatusCode() {
5182
}
5283

5384
/**
54-
* Gets the HTTP response.
85+
* Gets the error message.
86+
*
87+
* @return the error message
88+
*/
89+
public String getMessage() {
90+
return message;
91+
}
92+
93+
/**
94+
* Sets the error message.
95+
*
96+
* @param message the error message
97+
*/
98+
protected void setMessage(String message) {
99+
this.message = message;
100+
}
101+
102+
/**
103+
* Gets the headers.
104+
*
105+
* @return the headers
106+
*/
107+
public Headers getHeaders() {
108+
return headers;
109+
}
110+
111+
/**
112+
* Gets the response information other than the error message.
55113
*
56-
* @return the HTTP response
114+
* @return the response information other than the error message
57115
*/
58-
public Response getResponse() {
59-
return response;
116+
public Map<String, Object> getDebuggingInfo() {
117+
return debuggingInfo;
60118
}
61119
}

src/main/java/com/ibm/cloud/sdk/core/service/exception/ServiceUnavailableException.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ public class ServiceUnavailableException extends ServiceResponseException {
2929
/**
3030
* Instantiates a new Service Unavailable Exception.
3131
*
32-
* @param message the error message
3332
* @param response the HTTP response
3433
*/
35-
public ServiceUnavailableException(String message, Response response) {
36-
super(HttpStatus.SERVICE_UNAVAILABLE, message, response);
34+
public ServiceUnavailableException(Response response) {
35+
super(HttpStatus.SERVICE_UNAVAILABLE, response);
36+
if (this.getMessage() == null) {
37+
this.setMessage("Service unavailable");
38+
}
3739
}
3840

3941
}

src/main/java/com/ibm/cloud/sdk/core/service/exception/TooManyRequestsException.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,13 @@ public class TooManyRequestsException extends ServiceResponseException {
2828
/**
2929
* Instantiates a new Too Many Requests Exception.
3030
*
31-
* @param message the error message
3231
* @param response the HTTP response
3332
*/
34-
public TooManyRequestsException(String message, Response response) {
35-
super(TOO_MANY_REQUESTS, message, response);
33+
public TooManyRequestsException(Response response) {
34+
super(TOO_MANY_REQUESTS, response);
35+
if (this.getMessage() == null) {
36+
this.setMessage("Too many requests");
37+
}
3638
}
3739

3840
}

src/main/java/com/ibm/cloud/sdk/core/service/exception/UnauthorizedException.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ public class UnauthorizedException extends ServiceResponseException {
2929
/**
3030
* Instantiates a new Unauthorized Exception.
3131
*
32-
* @param message the error message
3332
* @param response the HTTP response
3433
*/
35-
public UnauthorizedException(String message, Response response) {
36-
super(HttpStatus.UNAUTHORIZED, message, response);
34+
public UnauthorizedException(Response response) {
35+
super(HttpStatus.UNAUTHORIZED, response);
36+
if (this.getMessage() == null) {
37+
this.setMessage("Unauthorized: Access is denied due to invalid credentials. Tip: Did you set the endpoint?");
38+
}
3739
}
3840

3941
}

0 commit comments

Comments
 (0)