Skip to content

Commit

Permalink
Improve error handling
Browse files Browse the repository at this point in the history
  • Loading branch information
seime committed Feb 17, 2023
1 parent 3f5b06d commit d178114
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -107,46 +107,51 @@ public <T> T sendRequest(final AbstractRequest req, final Type responseType) thr
public <T> T sendRequestInternal(final Request httpRequest, final AbstractRequest req, final Type responseType)
throws AugustException, ExecutionException, InterruptedException, TimeoutException {

final ContentResponse contentResponse = httpRequest.send();
String newAccessToken = contentResponse.getHeaders().get(HEADER_ACCESS_TOKEN);
if (accessToken == null || !accessToken.equals(newAccessToken)) {
listener.onAccessTokenUpdated(newAccessToken);
}
accessToken = newAccessToken;

final String responseJson = contentResponse.getContentAsString();
if (contentResponse.getStatus() == HttpStatus.OK_200) {
final JsonObject o = JsonParser.parseString(responseJson).getAsJsonObject();
if (o.has("message")) {
throw new RestCommunicationException(req, o.get("message").getAsString());
} else {
return gson.fromJson(responseJson, responseType);
try {
final ContentResponse contentResponse = httpRequest.send();
String newAccessToken = contentResponse.getHeaders().get(HEADER_ACCESS_TOKEN);
if (accessToken == null || !accessToken.equals(newAccessToken)) {
listener.onAccessTokenUpdated(newAccessToken);
}
} else if (contentResponse.getStatus() == HttpStatus.UNAUTHORIZED_401) {
if (accessToken == null) {
throw new RestCommunicationException("Could not renew token");
accessToken = newAccessToken;

final String responseJson = contentResponse.getContentAsString();
if (contentResponse.getStatus() == HttpStatus.OK_200) {
final JsonObject o = JsonParser.parseString(responseJson).getAsJsonObject();
if (o.has("message")) {
throw new RestCommunicationException(req, o.get("message").getAsString());
} else {
return gson.fromJson(responseJson, responseType);
}
} else if (contentResponse.getStatus() == HttpStatus.UNAUTHORIZED_401) {
if (accessToken == null) {
throw new RestCommunicationException("Could not renew token");
} else {
accessToken = null; // expired
return sendRequest(req, responseType); // Retry login + request
}

// See some error codes here;
// https://github.com/snjoetw/py-august/blob/78b25da03194d68d70115f36bf926a3a6443e555/august/api_async.py#L260

} else if (contentResponse.getStatus() == HttpStatus.FORBIDDEN_403) {
throw new ConfigurationException("Invalid credentials");
} else if (contentResponse.getStatus() == HttpStatus.REQUEST_TIMEOUT_408) {
throw new RestCommunicationException(
"The operation timed out because the bridge (connect) failed to respond");
} else if (contentResponse.getStatus() == HttpStatus.LOCKED_423) {
throw new RestCommunicationException("The operation failed because the bridge (connect) is in use");
} else if (contentResponse.getStatus() == HttpStatus.UNPROCESSABLE_ENTITY_422) {
throw new RestCommunicationException("The operation failed because the bridge (connect) is offline.");
} else if (contentResponse.getStatus() == HttpStatus.TOO_MANY_REQUESTS_429) {
throw new RestCommunicationException("Too many requests, reduce polling time");
} else {
accessToken = null; // expired
return sendRequest(req, responseType); // Retry login + request
throw new RestCommunicationException("Error sending request to server. Server responded with "
+ contentResponse.getStatus() + " and payload " + responseJson);
}

// See some error codes here;
// https://github.com/snjoetw/py-august/blob/78b25da03194d68d70115f36bf926a3a6443e555/august/api_async.py#L260

} else if (contentResponse.getStatus() == HttpStatus.FORBIDDEN_403) {
throw new ConfigurationException("Invalid credentials");
} else if (contentResponse.getStatus() == HttpStatus.REQUEST_TIMEOUT_408) {
} catch (Exception e) {
throw new RestCommunicationException(
"The operation timed out because the bridge (connect) failed to respond");
} else if (contentResponse.getStatus() == HttpStatus.LOCKED_423) {
throw new RestCommunicationException("The operation failed because the bridge (connect) is in use");
} else if (contentResponse.getStatus() == HttpStatus.UNPROCESSABLE_ENTITY_422) {
throw new RestCommunicationException("The operation failed because the bridge (connect) is offline.");
} else if (contentResponse.getStatus() == HttpStatus.TOO_MANY_REQUESTS_429) {
throw new RestCommunicationException("Too many requests, reduce polling time");
} else {
throw new RestCommunicationException("Error sending request to server. Server responded with "
+ contentResponse.getStatus() + " and payload " + responseJson);
String.format("Exception caught trying to communicate with API: %s", e.getMessage()), e);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,14 @@ public void initialize() {
break;
}

} catch (RestCommunicationException f) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, f.getMessage());
logger.warn("Error communicating with API. Will retry in 2 minutes", f);
statusFuture = Optional.of(scheduler.schedule(this::initialize, 2, TimeUnit.MINUTES));
} catch (AugustException e) {
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
"Internal error: " + e.getMessage());
logger.warn("Error logging in", e);
updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, "Internal error: " + e.getMessage()
+ "\nNew 2 factor login must be done by disabling and re-enabling bridge.");
logger.warn("Error logging in. Clearing all data, new l", e);
clearStorage();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -285,42 +285,47 @@ public void onPushMessage(String channelName, JsonElement message) {
if (remoteEvent != null) {
logger.info("Unhandled EVENT");
} else {
AsyncLockStatusDTO asyncStatus = gson.fromJson(message, new TypeToken<AsyncLockStatusDTO>() {
}.getType());

if (asyncStatus.lockStatus != null) {
State lockState = UnDefType.UNDEF;
switch (asyncStatus.lockStatus) {
case "locked":
lockState = OnOffType.ON;
break;
case "unlocked":
lockState = OnOffType.OFF;
break;
default:
logger.warn("Unexpected lockState from async message {}", asyncStatus.lockStatus);

if (message.getAsJsonObject().has("bridgeID")) {
logger.debug("Skipping bridge status push message");
} else {

AsyncLockStatusDTO asyncStatus = gson.fromJson(message, new TypeToken<AsyncLockStatusDTO>() {
}.getType());

if (asyncStatus.lockStatus != null) {
State lockState = UnDefType.UNDEF;
switch (asyncStatus.lockStatus) {
case "locked":
lockState = OnOffType.ON;
break;
case "unlocked":
lockState = OnOffType.OFF;
break;
default:
logger.warn("Unexpected lockState from async message {}", asyncStatus.lockStatus);
}
updateState(CHANNEL_LOCK_STATE, lockState);
}
updateState(CHANNEL_LOCK_STATE, lockState);
}

if (asyncStatus.doorStatus != null) {
State doorState = UnDefType.UNDEF;
switch (asyncStatus.doorStatus) {
case "open":
doorState = OpenClosedType.OPEN;
break;
case "closed":
doorState = OpenClosedType.CLOSED;
break;
default:
logger.warn("Unexpected doorState from async message {}", asyncStatus.doorStatus);
if (asyncStatus.doorStatus != null) {
State doorState = UnDefType.UNDEF;
switch (asyncStatus.doorStatus) {
case "open":
doorState = OpenClosedType.OPEN;
break;
case "closed":
doorState = OpenClosedType.CLOSED;
break;
default:
logger.warn("Unexpected doorState from async message {}", asyncStatus.doorStatus);
}
updateState(CHANNEL_DOOR_STATE, doorState);
}
if (asyncStatus.callingUserID != null) {
updateState(CHANNEL_CHANGED_BY_USER, getLastChangeBy(asyncStatus.callingUserID));
}
updateState(CHANNEL_DOOR_STATE, doorState);
}
if (asyncStatus.callingUserID != null) {
updateState(CHANNEL_CHANGED_BY_USER, getLastChangeBy(asyncStatus.callingUserID));
}

}
} catch (Exception e) {
logger.error("Error handling pubnub message on channel {}: {}", channelName, message, e);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"status": "associated_bridge_online",
"bridgeID": "BridgeID",
"bridgeSerial": "SERIAL",
"lockID": "LockID"
}

0 comments on commit d178114

Please sign in to comment.