Skip to content

Commit

Permalink
Utilities for correctly handling json parsing errors on network respo…
Browse files Browse the repository at this point in the history
…nses.
  • Loading branch information
alan-signal committed Oct 9, 2020
1 parent 597d16f commit 07b0d8c
Showing 1 changed file with 52 additions and 59 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -404,12 +404,7 @@ public SignalServiceMessagesResult getMessages() throws IOException {
Response response = makeServiceRequest(String.format(MESSAGE_PATH, ""), "GET", (RequestBody) null, NO_HEADERS, NO_HANDLER, Optional.absent());
validateServiceResponse(response);

List<SignalServiceEnvelopeEntity> envelopes;
try {
envelopes = JsonUtil.fromJson(readBodyString(response.body()), SignalServiceEnvelopeEntityList.class).getMessages();
} catch (IOException e) {
throw new PushNetworkException(e);
}
List<SignalServiceEnvelopeEntity> envelopes = readBodyJson(response.body(), SignalServiceEnvelopeEntityList.class).getMessages();

long serverDeliveredTimestamp = 0;
try {
Expand Down Expand Up @@ -1346,11 +1341,7 @@ private ListenableFuture<String> submitServiceRequest(String urlFragment, String
@Override
public void onResponse(Call call, Response response) {
try (ResponseBody body = validateServiceResponse(response).body()) {
try {
bodyFuture.set(readBodyString(body));
} catch (IOException e) {
throw new PushNetworkException(e);
}
bodyFuture.set(readBodyString(body));
} catch (IOException e) {
bodyFuture.setException(e);
}
Expand Down Expand Up @@ -1392,9 +1383,8 @@ private Response makeServiceRequest(String urlFragment,
}

private Response validateServiceResponse(Response response) throws NonSuccessfulResponseCodeException, PushNetworkException {
int responseCode = response.code();
String responseMessage = response.message();
ResponseBody responseBody = response.body();
int responseCode = response.code();
String responseMessage = response.message();

switch (responseCode) {
case 413:
Expand All @@ -1405,58 +1395,23 @@ private Response validateServiceResponse(Response response) throws NonSuccessful
case 404:
throw new NotFoundException("Not found");
case 409:
MismatchedDevices mismatchedDevices;

try {
mismatchedDevices = JsonUtil.fromJson(readBodyString(responseBody), MismatchedDevices.class);
} catch (JsonProcessingException e) {
Log.w(TAG, e);
throw new NonSuccessfulResponseCodeException("Bad response: " + responseCode + " " + responseMessage);
} catch (IOException e) {
throw new PushNetworkException(e);
}
MismatchedDevices mismatchedDevices = readResponseJson(response, MismatchedDevices.class);

throw new MismatchedDevicesException(mismatchedDevices);
case 410:
StaleDevices staleDevices;

try {
staleDevices = JsonUtil.fromJson(readBodyString(responseBody), StaleDevices.class);
} catch (JsonProcessingException e) {
throw new NonSuccessfulResponseCodeException("Bad response: " + responseCode + " " + responseMessage);
} catch (IOException e) {
throw new PushNetworkException(e);
}
StaleDevices staleDevices = readResponseJson(response, StaleDevices.class);

throw new StaleDevicesException(staleDevices);
case 411:
DeviceLimit deviceLimit;

try {
deviceLimit = JsonUtil.fromJson(readBodyString(responseBody), DeviceLimit.class);
} catch (JsonProcessingException e) {
throw new NonSuccessfulResponseCodeException("Bad response: " + responseCode + " " + responseMessage);
} catch (IOException e) {
throw new PushNetworkException(e);
}
DeviceLimit deviceLimit = readResponseJson(response, DeviceLimit.class);

throw new DeviceLimitExceededException(deviceLimit);
case 417:
throw new ExpectationFailedException();
case 423:
RegistrationLockFailure accountLockFailure;

try {
accountLockFailure = JsonUtil.fromJson(readBodyString(responseBody), RegistrationLockFailure.class);
} catch (JsonProcessingException e) {
Log.w(TAG, e);
throw new NonSuccessfulResponseCodeException("Bad response: " + responseCode + " " + responseMessage);
} catch (IOException e) {
throw new PushNetworkException(e);
}

AuthCredentials credentials = accountLockFailure.backupCredentials;
String basicStorageCredentials = credentials != null ? credentials.asBasic() : null;
RegistrationLockFailure accountLockFailure = readResponseJson(response, RegistrationLockFailure.class);
AuthCredentials credentials = accountLockFailure.backupCredentials;
String basicStorageCredentials = credentials != null ? credentials.asBasic() : null;

throw new LockedException(accountLockFailure.length,
accountLockFailure.timeRemaining,
Expand Down Expand Up @@ -1797,14 +1752,52 @@ private static byte[] readBodyBytes(ResponseBody response) throws PushNetworkExc
}
}

private static String readBodyString(ResponseBody body) throws IOException {
if (body != null) {
/**
* Converts {@link IOException} on body reading to {@link PushNetworkException}.
*/
private static String readBodyString(ResponseBody body) throws PushNetworkException {
if (body == null) {
throw new PushNetworkException("No body!");
}

try {
return body.string();
} else {
throw new IOException("No body!");
} catch (IOException e) {
throw new PushNetworkException(e);
}
}

/**
* Converts {@link IOException} on body reading to {@link PushNetworkException}.
* {@link IOException} during json parsing is converted to a {@link NonSuccessfulResponseCodeException}
*/
private static <T> T readBodyJson(ResponseBody body, Class<T> clazz)
throws PushNetworkException, NonSuccessfulResponseCodeException
{
String json = readBodyString(body);
try {
return JsonUtil.fromJson(json, clazz);
} catch (JsonProcessingException e) {
Log.w(TAG, e);
throw new NonSuccessfulResponseCodeException("Unable to parse entity");
} catch (IOException e) {
throw new PushNetworkException(e);
}
}

/**
* Converts {@link IOException} on body reading to {@link PushNetworkException}.
* {@link IOException} during json parsing is converted to a {@link NonSuccessfulResponseCodeException} with response code detail.
*/
private static <T> T readResponseJson(Response response, Class<T> clazz)
throws PushNetworkException, NonSuccessfulResponseCodeException
{
try {
return readBodyJson(response.body(), clazz);
} catch (NonSuccessfulResponseCodeException e) {
throw new NonSuccessfulResponseCodeException("Bad response: " + response.code() + " " + response.message());
}
}

private static class GcmRegistrationId {

Expand Down

0 comments on commit 07b0d8c

Please sign in to comment.