Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Hopefully the most correct way to process a JAX-RS Response and convert it to a Throwable, without losing other Throwables that may happen along the way.
public static final <T extends Throwable> T toThrowable(final Class<T> throwableClass, final Throwable cause, Response response) {
Objects.requireNonNull(throwableClass, "throwableClass == null");
Constructor<T> c = null;
try {
c = throwableClass.getConstructor(String.class, Throwable.class);
} catch (final NoSuchMethodException e) {
throw new IllegalArgumentException("throwableClass", e);
}
assert c != null : throwableClass + ".getConstructor(String.class, Throwable.class) == null";
T returnValue = null;
String message = null;
if (cause != null) {
message = cause.getMessage();
}
if (response == null || !MediaType.APPLICATION_JSON_TYPE.isCompatible(response.getMediaType())) {
try {
returnValue = c.newInstance(message, cause);
} catch (final IllegalAccessException | InstantiationException | InvocationTargetException e) {
throw new IllegalArgumentException("throwableClass", e);
}
} else {
try {
if (response.bufferEntity()) {
final JsonObject payload = response.readEntity(JsonObject.class);
assert payload != null : "response.readEntity(JsonObject.class) == null";
// See https://tools.ietf.org/html/rfc7807.
final JsonValue detailValue = payload.get("detail");
if (detailValue != null && detailValue instanceof JsonString) {
message = ((JsonString)detailValue).getString();
}
}
assert returnValue == null : "returnValue != null: " + returnValue;
returnValue = c.newInstance(message, cause);
} catch (final IllegalAccessException | InstantiationException | InvocationTargetException constructorInvocationFailed) {
response = null;
throw new IllegalArgumentException("throwableClass", constructorInvocationFailed);
} catch (final IllegalStateException | ProcessingException responseReadEntityFailed) {
assert returnValue == null : "returnValue != null: " + returnValue;
try {
returnValue = c.newInstance(message, cause);
} catch (final IllegalAccessException | InstantiationException | InvocationTargetException constructorInvocationFailed) {
response = null;
final IllegalArgumentException e = new IllegalArgumentException("throwableClass", constructorInvocationFailed);
e.addSuppressed(responseReadEntityFailed);
throw e;
}
returnValue.addSuppressed(responseReadEntityFailed);
} finally {
if (response != null) {
try {
response.close();
} catch (final ProcessingException responseClosingFailed) {
if (returnValue == null) {
try {
returnValue = c.newInstance(message, cause);
} catch (final IllegalAccessException | InstantiationException | InvocationTargetException constructorInvocationFailed) {
final IllegalArgumentException e = new IllegalArgumentException("throwableClass", constructorInvocationFailed);
e.addSuppressed(responseClosingFailed);
throw e;
}
}
returnValue.addSuppressed(responseClosingFailed);
}
}
}
}
assert returnValue != null : "returnValue == null";
return returnValue;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment