]> git.basschouten.com Git - openhab-addons.git/commitdiff
[openuv] Enhance server side error handling (#12958)
authorGaël L'hopital <gael@lhopital.org>
Sun, 19 Jun 2022 12:56:56 +0000 (14:56 +0200)
committerGitHub <noreply@github.com>
Sun, 19 Jun 2022 12:56:56 +0000 (14:56 +0200)
* Enhance server side error handling
* Enhancing exception tree
* a small factorization of error status
* Shorten statusMessage
* Correcting log syntax

Signed-off-by: clinique <gael@lhopital.org>
bundles/org.openhab.binding.openuv/src/main/java/org/openhab/binding/openuv/internal/handler/OpenUVBridgeHandler.java
bundles/org.openhab.binding.openuv/src/main/resources/OH-INF/i18n/openuv.properties

index 17e267baeedb339b3f22a9ce64fc398d66457b81..ddf5082a1e06edd301f40b785dd3ee81f89432cf 100644 (file)
@@ -59,6 +59,7 @@ import com.google.gson.JsonSyntaxException;
 @NonNullByDefault
 public class OpenUVBridgeHandler extends BaseBridgeHandler {
     private static final String QUERY_URL = "https://api.openuv.io/api/v1/uv?lat=%s&lng=%s&alt=%s";
+    private static final int RECONNECT_DELAY_MIN = 5;
     private static final int REQUEST_TIMEOUT_MS = (int) TimeUnit.SECONDS.toMillis(30);
 
     private final Logger logger = LoggerFactory.getLogger(OpenUVBridgeHandler.class);
@@ -69,6 +70,7 @@ public class OpenUVBridgeHandler extends BaseBridgeHandler {
     private final LocaleProvider localeProvider;
 
     private Optional<ScheduledFuture<?>> reconnectJob = Optional.empty();
+    private boolean keyVerified;
 
     public OpenUVBridgeHandler(Bridge bridge, LocationProvider locationProvider, TranslationProvider i18nProvider,
             LocaleProvider localeProvider, Gson gson) {
@@ -82,6 +84,7 @@ public class OpenUVBridgeHandler extends BaseBridgeHandler {
     @Override
     public void initialize() {
         logger.debug("Initializing OpenUV API bridge handler.");
+        keyVerified = false;
         BridgeConfiguration config = getConfigAs(BridgeConfiguration.class);
         if (config.apikey.isEmpty()) {
             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
@@ -94,8 +97,7 @@ public class OpenUVBridgeHandler extends BaseBridgeHandler {
 
     @Override
     public void dispose() {
-        reconnectJob.ifPresent(job -> job.cancel(true));
-        reconnectJob = Optional.empty();
+        freeReconnectJob();
     }
 
     @Override
@@ -113,6 +115,8 @@ public class OpenUVBridgeHandler extends BaseBridgeHandler {
     }
 
     public @Nullable OpenUVResult getUVData(String latitude, String longitude, String altitude) {
+        String statusMessage = "";
+        ThingStatusDetail statusDetail = ThingStatusDetail.COMMUNICATION_ERROR;
         String url = String.format(QUERY_URL, latitude, longitude, altitude);
         String jsonData = "";
         try {
@@ -122,33 +126,53 @@ public class OpenUVBridgeHandler extends BaseBridgeHandler {
                 String error = uvResponse.getError();
                 if (error == null) {
                     updateStatus(ThingStatus.ONLINE);
+                    keyVerified = true;
                     return uvResponse.getResult();
                 }
                 throw new OpenUVException(error);
             }
         } catch (JsonSyntaxException e) {
-            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR,
-                    String.format("Invalid json received when calling `%s` : %s", url, jsonData));
+            if (jsonData.contains("MongoError")) {
+                statusMessage = String.format("@text/offline.comm-error-faultly-service [ \"%d\" ]",
+                        RECONNECT_DELAY_MIN);
+                scheduleReconnectJob(RECONNECT_DELAY_MIN);
+            } else {
+                statusDetail = ThingStatusDetail.NONE;
+                statusMessage = String.format("@text/offline.invalid-json [ \"%s\" ]", url);
+                logger.debug("{} : {}", statusMessage, jsonData);
+            }
         } catch (IOException e) {
-            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, e.getMessage());
+            statusMessage = e.getMessage();
         } catch (OpenUVException e) {
             if (e.isQuotaError()) {
-                LocalDateTime tomorrowMidnight = LocalDate.now().plusDays(1).atStartOfDay().plusMinutes(2);
-
-                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.COMMUNICATION_ERROR, String
-                        .format("@text/offline.comm-error-quota-exceeded [ \"%s\" ]", tomorrowMidnight.toString()));
-
-                reconnectJob = Optional.of(scheduler.schedule(this::initiateConnexion,
-                        Duration.between(LocalDateTime.now(), tomorrowMidnight).toMinutes(), TimeUnit.MINUTES));
-            } else {
-                updateStatus(ThingStatus.OFFLINE,
-                        e.isApiKeyError() ? ThingStatusDetail.CONFIGURATION_ERROR : ThingStatusDetail.NONE,
-                        e.getMessage());
+                LocalDateTime nextMidnight = LocalDate.now().plusDays(1).atStartOfDay().plusMinutes(2);
+                statusMessage = String.format("@text/offline.comm-error-quota-exceeded [ \"%s\" ]",
+                        nextMidnight.toString());
+                scheduleReconnectJob(Duration.between(LocalDateTime.now(), nextMidnight).toMinutes());
+            } else if (e.isApiKeyError()) {
+                if (keyVerified) {
+                    statusMessage = String.format("@text/offline.api-key-not-recognized [ \"%d\" ]",
+                            RECONNECT_DELAY_MIN);
+                    scheduleReconnectJob(RECONNECT_DELAY_MIN);
+                } else {
+                    statusDetail = ThingStatusDetail.CONFIGURATION_ERROR;
+                }
             }
         }
+        updateStatus(ThingStatus.OFFLINE, statusDetail, statusMessage);
         return null;
     }
 
+    private void scheduleReconnectJob(long delay) {
+        freeReconnectJob();
+        reconnectJob = Optional.of(scheduler.schedule(this::initiateConnexion, delay, TimeUnit.MINUTES));
+    }
+
+    private void freeReconnectJob() {
+        reconnectJob.ifPresent(job -> job.cancel(true));
+        reconnectJob = Optional.empty();
+    }
+
     @Override
     public Collection<Class<? extends ThingHandlerService>> getServices() {
         return Set.of(OpenUVDiscoveryService.class);
index c942051dfd1448d93b1972ed33a49a38c18fc720..2f7010461c2f0c47fd02983d396baa3d5d5513f1 100644 (file)
@@ -66,6 +66,9 @@ channel-type.config.openuv.SafeExposure.index.option.VI = Black
 offline.config-error-unknown-apikey = Parameter 'apikey' must be configured.
 offline.config-error-invalid-refresh = Parameter 'refresh' must be higher than 3 minutes to stay in free API plan.
 offline.comm-error-quota-exceeded = Quota Exceeded, going OFFLINE for today, will retry at : {0}
+offline.comm-error-faultly-service = Service not responding, will reconnect in {0} minutes
+offline.invalid-json = Invalid JSON received when calling `{0}`
+offline.api-key-not-recognized = Service error while API key is known correct, will reconnect in {0} minutes
 
 # discovery result