Skip to content

Commit

Permalink
[hue] Handle unexpected empty response from API (#14297)
Browse files Browse the repository at this point in the history
Fix #14218

Signed-off-by: Laurent Garnier <lg.hc@free.fr>
  • Loading branch information
lolodomo authored Feb 1, 2023
1 parent 38fa097 commit c162e66
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
import org.openhab.binding.hue.internal.dto.Util;
import org.openhab.binding.hue.internal.exceptions.ApiException;
import org.openhab.binding.hue.internal.exceptions.DeviceOffException;
import org.openhab.binding.hue.internal.exceptions.EmptyResponseException;
import org.openhab.binding.hue.internal.exceptions.EntityNotAvailableException;
import org.openhab.binding.hue.internal.exceptions.GroupTableFullException;
import org.openhab.binding.hue.internal.exceptions.InvalidCommandException;
Expand Down Expand Up @@ -252,6 +253,10 @@ private <T extends HueObject> List<T> getTypedLights(Type gsonType)

handleErrors(result);

if (result.body.isBlank()) {
throw new EmptyResponseException("GET request 'lights' returned an unexpected empty reponse");
}

Map<String, T> lightMap = safeFromJson(result.body, gsonType);
List<T> lights = new ArrayList<>();
lightMap.forEach((id, light) -> {
Expand All @@ -275,6 +280,10 @@ public List<FullSensor> getSensors()

handleErrors(result);

if (result.body.isBlank()) {
throw new EmptyResponseException("GET request 'sensors' returned an unexpected empty reponse");
}

Map<String, FullSensor> sensorMap = safeFromJson(result.body, FullSensor.GSON_TYPE);
List<FullSensor> sensors = new ArrayList<>();
sensorMap.forEach((id, sensor) -> {
Expand All @@ -300,6 +309,10 @@ public List<FullSensor> getSensors()

handleErrors(result);

if (result.body.isBlank()) {
throw new EmptyResponseException("GET request 'lights/new' returned an unexpected empty reponse");
}

String lastScan = safeFromJson(result.body, NewLightsResponse.class).lastscan;

switch (lastScan) {
Expand Down Expand Up @@ -362,6 +375,11 @@ public FullHueObject getLight(HueObject light)

handleErrors(result);

if (result.body.isBlank()) {
throw new EmptyResponseException(
"GET request 'lights/" + enc(light.getId()) + "' returned an unexpected empty reponse");
}

FullHueObject fullLight = safeFromJson(result.body, FullLight.class);
fullLight.setId(light.getId());
return fullLight;
Expand All @@ -386,6 +404,11 @@ public String setLightName(HueObject light, String name)

handleErrors(result);

if (result.body.isBlank()) {
throw new EmptyResponseException(
"PUT request 'lights/" + enc(light.getId()) + "' returned an unexpected empty reponse");
}

List<SuccessResponse> entries = safeFromJson(result.body, SuccessResponse.GSON_TYPE);
SuccessResponse response = entries.get(0);

Expand Down Expand Up @@ -469,6 +492,10 @@ public List<FullGroup> getGroups()

handleErrors(result);

if (result.body.isBlank()) {
throw new EmptyResponseException("GET request 'groups' returned an unexpected empty reponse");
}

Map<String, FullGroup> groupMap = safeFromJson(result.body, FullGroup.GSON_TYPE);
List<FullGroup> groups = new ArrayList<>();
if (groupMap.get("0") == null) {
Expand Down Expand Up @@ -510,6 +537,10 @@ public Group createGroup(List<HueObject> lights)

handleErrors(result);

if (result.body.isBlank()) {
throw new EmptyResponseException("POST request 'groups' returned an unexpected empty reponse");
}

List<SuccessResponse> entries = safeFromJson(result.body, SuccessResponse.GSON_TYPE);
SuccessResponse response = entries.get(0);

Expand Down Expand Up @@ -540,6 +571,10 @@ public Group createGroup(String name, List<HueObject> lights)

handleErrors(result);

if (result.body.isBlank()) {
throw new EmptyResponseException("POST request 'groups' returned an unexpected empty reponse");
}

List<SuccessResponse> entries = safeFromJson(result.body, SuccessResponse.GSON_TYPE);
SuccessResponse response = entries.get(0);

Expand All @@ -565,6 +600,11 @@ public FullGroup getGroup(Group group)

handleErrors(result);

if (result.body.isBlank()) {
throw new EmptyResponseException(
"GET request 'groups/" + enc(group.getId()) + "' returned an unexpected empty reponse");
}

FullGroup fullGroup = safeFromJson(result.body, FullGroup.class);
fullGroup.setId(group.getId());
return fullGroup;
Expand Down Expand Up @@ -593,6 +633,11 @@ public String setGroupName(Group group, String name)

handleErrors(result);

if (result.body.isBlank()) {
throw new EmptyResponseException(
"PUT request 'groups/" + enc(group.getId()) + "' returned an unexpected empty reponse");
}

List<SuccessResponse> entries = safeFromJson(result.body, SuccessResponse.GSON_TYPE);
SuccessResponse response = entries.get(0);

Expand Down Expand Up @@ -648,6 +693,11 @@ public String setGroupAttributes(Group group, String name, List<HueObject> light

handleErrors(result);

if (result.body.isBlank()) {
throw new EmptyResponseException(
"PUT request 'groups/" + enc(group.getId()) + "' returned an unexpected empty reponse");
}

List<SuccessResponse> entries = safeFromJson(result.body, SuccessResponse.GSON_TYPE);
SuccessResponse response = entries.get(0);

Expand Down Expand Up @@ -707,6 +757,10 @@ public List<Schedule> getSchedules()

handleErrors(result);

if (result.body.isBlank()) {
throw new EmptyResponseException("GET request 'schedules' returned an unexpected empty reponse");
}

Map<String, Schedule> scheduleMap = safeFromJson(result.body, Schedule.GSON_TYPE);
List<Schedule> schedules = new ArrayList<>();
scheduleMap.forEach((id, schedule) -> {
Expand Down Expand Up @@ -761,6 +815,10 @@ public List<Scene> getScenes() throws IOException, ApiException, ConfigurationEx

handleErrors(result);

if (result.body.isBlank()) {
throw new EmptyResponseException("GET request 'scenes' returned an unexpected empty reponse");
}

Map<String, Scene> sceneMap = safeFromJson(result.body, Scene.GSON_TYPE);
return sceneMap.entrySet().stream()//
.map(e -> {
Expand Down Expand Up @@ -841,6 +899,10 @@ private String link(CreateUserRequest request)

handleErrors(result);

if (result.body.isBlank()) {
throw new EmptyResponseException("POST request (link) returned an unexpected empty reponse");
}

List<SuccessResponse> entries = safeFromJson(result.body, SuccessResponse.GSON_TYPE);
SuccessResponse response = entries.get(0);

Expand All @@ -865,6 +927,10 @@ public Config getConfig() throws IOException, ApiException, ConfigurationExcepti

handleErrors(result);

if (result.body.isBlank()) {
throw new EmptyResponseException("GET request 'config' returned an unexpected empty reponse");
}

return safeFromJson(result.body, Config.class);
}

Expand Down Expand Up @@ -912,6 +978,10 @@ public FullConfig getFullConfig() throws IOException, ApiException, Configuratio

handleErrors(result);

if (result.body.isBlank()) {
throw new EmptyResponseException("GET request (getFullConfig) returned an unexpected empty reponse");
}

FullConfig fullConfig = gson.fromJson(result.body, FullConfig.class);
return Objects.requireNonNull(fullConfig);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* Copyright (c) 2010-2023 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.hue.internal.exceptions;

import org.eclipse.jdt.annotation.NonNullByDefault;

/**
* Thrown when API is returning an unexpected empty response.
*
* @author Laurent Garnier - Initial contribution
*/
@SuppressWarnings("serial")
@NonNullByDefault
public class EmptyResponseException extends ApiException {
public EmptyResponseException() {
}

public EmptyResponseException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import org.openhab.binding.hue.internal.dto.StateUpdate;
import org.openhab.binding.hue.internal.exceptions.ApiException;
import org.openhab.binding.hue.internal.exceptions.DeviceOffException;
import org.openhab.binding.hue.internal.exceptions.EmptyResponseException;
import org.openhab.binding.hue.internal.exceptions.EntityNotAvailableException;
import org.openhab.binding.hue.internal.exceptions.LinkButtonException;
import org.openhab.binding.hue.internal.exceptions.UnauthorizedException;
Expand Down Expand Up @@ -150,6 +151,9 @@ public void run() {
lastBridgeConnectionState = false;
onConnectionLost();
}
} catch (EmptyResponseException e) {
// Unexpected empty response is ignored
logger.debug("{}", e.getMessage());
} catch (ApiException | CommunicationException | IOException e) {
if (hueBridge != null && lastBridgeConnectionState) {
logger.debug("Connection to Hue Bridge {} lost: {}", hueBridge.getIPAddress(), e.getMessage(), e);
Expand Down

0 comments on commit c162e66

Please sign in to comment.