]> git.basschouten.com Git - openhab-addons.git/commitdiff
[pushover] Improved exception handling (#12023)
authorChristoph Weitkamp <github@christophweitkamp.de>
Sun, 16 Jan 2022 17:07:36 +0000 (18:07 +0100)
committerGitHub <noreply@github.com>
Sun, 16 Jan 2022 17:07:36 +0000 (18:07 +0100)
* Improved exception handling

Signed-off-by: Christoph Weitkamp <github@christophweitkamp.de>
bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/PushoverBindingConstants.java
bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/connection/PushoverAPIConnection.java
bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/connection/PushoverCommunicationException.java [deleted file]
bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/connection/PushoverConfigurationException.java [deleted file]
bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/connection/PushoverMessageBuilder.java
bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/handler/PushoverAccountHandler.java
bundles/org.openhab.binding.pushover/src/main/resources/OH-INF/i18n/pushover.properties
bundles/org.openhab.binding.pushover/src/test/java/org/openhab/binding/pushover/internal/actions/PushoverActionsTest.java

index f3a31c15c1f66d436f1a6f69820ff6ab6224f9ce..28231c407a2b3f51f5f0a361f3b9d2c9cb1cb342 100644 (file)
@@ -31,4 +31,10 @@ public class PushoverBindingConstants {
 
     public static final String DEFAULT_SOUND = "default";
     public static final String DEFAULT_TITLE = "openHAB";
+
+    public static final String TEXT_OFFLINE_COMMUNICATION_ERROR = "@text/offline.communication-error";
+    public static final String TEXT_OFFLINE_CONF_ERROR_MISSING_APIKEY = "@text/offline.conf-error-missing-apikey";
+    public static final String TEXT_OFFLINE_CONF_ERROR_MISSING_USER = "@text/offline.conf-error-missing-user";
+    public static final String TEXT_OFFLINE_CONF_ERROR_UNKNOWN = "@text/offline.conf-error-unknown";
+    public static final String TEXT_ERROR_SKIP_SENDING_MESSAGE = "@text/error.skip-sending-message";
 }
index 5f29b28118219c836f5db899bdd129a66d601d5b..2c9d756381a5de7fdcfdb0533f21d96f6e61062e 100644 (file)
  */
 package org.openhab.binding.pushover.internal.connection;
 
+import static org.openhab.binding.pushover.internal.PushoverBindingConstants.*;
+
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
-import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ExecutionException;
@@ -32,13 +33,16 @@ import org.eclipse.jetty.http.HttpMethod;
 import org.eclipse.jetty.http.HttpStatus;
 import org.openhab.binding.pushover.internal.config.PushoverAccountConfiguration;
 import org.openhab.binding.pushover.internal.dto.Sound;
-import org.openhab.core.cache.ExpiringCacheMap;
+import org.openhab.core.cache.ExpiringCache;
+import org.openhab.core.i18n.CommunicationException;
+import org.openhab.core.i18n.ConfigurationException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.gson.JsonElement;
 import com.google.gson.JsonObject;
 import com.google.gson.JsonParser;
+import com.google.gson.JsonSyntaxException;
 
 /**
  * The {@link PushoverAPIConnection} is responsible for handling the connections to Pushover Messages API.
@@ -48,62 +52,74 @@ import com.google.gson.JsonParser;
 @NonNullByDefault
 public class PushoverAPIConnection {
 
+    private static final String JSON_VALUE_ERRORS = "errors";
+    private static final String JSON_VALUE_RECEIPT = "receipt";
+    private static final String JSON_VALUE_SOUNDS = "sounds";
+    private static final String JSON_VALUE_STATUS = "status";
+
     private final Logger logger = LoggerFactory.getLogger(PushoverAPIConnection.class);
 
     private static final String VALIDATE_URL = "https://api.pushover.net/1/users/validate.json";
     private static final String MESSAGE_URL = "https://api.pushover.net/1/messages.json";
-    private static final String CANCEL_MESSAGE_URL = "https://api.pushover.net/1/receipts/{receipt}/cancel.json";
+    private static final String CANCEL_MESSAGE_URL = "https://api.pushover.net/1/receipts/%s/cancel.json";
     private static final String SOUNDS_URL = "https://api.pushover.net/1/sounds.json";
 
     private final HttpClient httpClient;
     private final PushoverAccountConfiguration config;
 
-    private final ExpiringCacheMap<String, String> cache = new ExpiringCacheMap<>(TimeUnit.DAYS.toMillis(1));
+    private final ExpiringCache<List<Sound>> cache = new ExpiringCache<>(TimeUnit.DAYS.toMillis(1),
+            this::getSoundsFromSource);
 
     public PushoverAPIConnection(HttpClient httpClient, PushoverAccountConfiguration config) {
         this.httpClient = httpClient;
         this.config = config;
     }
 
-    public boolean validateUser() throws PushoverCommunicationException, PushoverConfigurationException {
+    public boolean validateUser() throws CommunicationException, ConfigurationException {
         return getMessageStatus(
                 post(VALIDATE_URL, PushoverMessageBuilder.getInstance(config.apikey, config.user).build()));
     }
 
-    public boolean sendMessage(PushoverMessageBuilder message)
-            throws PushoverCommunicationException, PushoverConfigurationException {
+    public boolean sendMessage(PushoverMessageBuilder message) throws CommunicationException, ConfigurationException {
         return getMessageStatus(post(MESSAGE_URL, message.build()));
     }
 
     public String sendPriorityMessage(PushoverMessageBuilder message)
-            throws PushoverCommunicationException, PushoverConfigurationException {
+            throws CommunicationException, ConfigurationException {
         final JsonObject json = JsonParser.parseString(post(MESSAGE_URL, message.build())).getAsJsonObject();
-        return getMessageStatus(json) && json.has("receipt") ? json.get("receipt").getAsString() : "";
+        return getMessageStatus(json) && json.has(JSON_VALUE_RECEIPT) ? json.get(JSON_VALUE_RECEIPT).getAsString() : "";
     }
 
-    public boolean cancelPriorityMessage(String receipt)
-            throws PushoverCommunicationException, PushoverConfigurationException {
-        return getMessageStatus(post(CANCEL_MESSAGE_URL.replace("{receipt}", receipt),
+    public boolean cancelPriorityMessage(String receipt) throws CommunicationException, ConfigurationException {
+        return getMessageStatus(post(String.format(CANCEL_MESSAGE_URL, receipt),
                 PushoverMessageBuilder.getInstance(config.apikey, config.user).build()));
     }
 
-    public List<Sound> getSounds() throws PushoverCommunicationException, PushoverConfigurationException {
+    public @Nullable List<Sound> getSounds() {
+        return cache.getValue();
+    }
+
+    private List<Sound> getSoundsFromSource() throws CommunicationException, ConfigurationException {
         final String localApikey = config.apikey;
-        if (localApikey == null || localApikey.isEmpty()) {
-            throw new PushoverConfigurationException("@text/offline.conf-error-missing-apikey");
+        if (localApikey == null || localApikey.isBlank()) {
+            throw new ConfigurationException(TEXT_OFFLINE_CONF_ERROR_MISSING_APIKEY);
         }
 
-        final Map<String, String> params = new HashMap<>(1);
-        params.put(PushoverMessageBuilder.MESSAGE_KEY_TOKEN, localApikey);
-
-        // TODO do not cache the response, cache the parsed list of sounds
-        final String content = getFromCache(buildURL(SOUNDS_URL, params));
-        final JsonObject json = content == null ? null : JsonParser.parseString(content).getAsJsonObject();
-        final JsonObject sounds = json == null || !json.has("sounds") ? null : json.get("sounds").getAsJsonObject();
-
-        return sounds == null ? List.of()
-                : sounds.entrySet().stream().map(entry -> new Sound(entry.getKey(), entry.getValue().getAsString()))
+        try {
+            final String content = get(
+                    buildURL(SOUNDS_URL, Map.of(PushoverMessageBuilder.MESSAGE_KEY_TOKEN, localApikey)));
+            final JsonObject json = JsonParser.parseString(content).getAsJsonObject();
+            final JsonObject sounds = json.has(JSON_VALUE_SOUNDS) ? json.get(JSON_VALUE_SOUNDS).getAsJsonObject()
+                    : null;
+            if (sounds != null) {
+                return sounds.entrySet().stream()
+                        .map(entry -> new Sound(entry.getKey(), entry.getValue().getAsString()))
                         .collect(Collectors.toUnmodifiableList());
+            }
+        } catch (JsonSyntaxException e) {
+            // do nothing
+        }
+        return List.of();
     }
 
     private String buildURL(String url, Map<String, String> requestParams) {
@@ -115,21 +131,16 @@ public class PushoverAPIConnection {
         return value == null ? "" : URLEncoder.encode(value, StandardCharsets.UTF_8);
     }
 
-    private @Nullable String getFromCache(String url) {
-        return cache.putIfAbsentAndGet(url, () -> get(url));
-    }
-
-    private String get(String url) throws PushoverCommunicationException, PushoverConfigurationException {
+    private String get(String url) throws CommunicationException, ConfigurationException {
         return executeRequest(HttpMethod.GET, url, null);
     }
 
-    private String post(String url, ContentProvider body)
-            throws PushoverCommunicationException, PushoverConfigurationException {
+    private String post(String url, ContentProvider body) throws CommunicationException, ConfigurationException {
         return executeRequest(HttpMethod.POST, url, body);
     }
 
     private synchronized String executeRequest(HttpMethod httpMethod, String url, @Nullable ContentProvider body)
-            throws PushoverCommunicationException, PushoverConfigurationException {
+            throws CommunicationException, ConfigurationException {
         logger.trace("Pushover request: {} - URL = '{}'", httpMethod, url);
         try {
             final Request request = httpClient.newRequest(url).method(httpMethod).timeout(config.timeout,
@@ -152,35 +163,43 @@ public class PushoverAPIConnection {
                     return content;
                 case HttpStatus.BAD_REQUEST_400:
                     logger.debug("Pushover server responded with status code {}: {}", httpStatus, content);
-                    throw new PushoverConfigurationException(getMessageError(content));
+                    throw new ConfigurationException(getMessageError(content));
                 default:
                     logger.debug("Pushover server responded with status code {}: {}", httpStatus, content);
-                    throw new PushoverCommunicationException(content);
+                    throw new CommunicationException(content);
             }
         } catch (ExecutionException e) {
-            logger.debug("Exception occurred during execution: {}", e.getLocalizedMessage(), e);
-            throw new PushoverCommunicationException(e.getLocalizedMessage(), e.getCause());
-        } catch (InterruptedException | TimeoutException e) {
-            logger.debug("Exception occurred during execution: {}", e.getLocalizedMessage(), e);
-            throw new PushoverCommunicationException(e.getLocalizedMessage());
+            String message = e.getMessage();
+            logger.debug("ExecutionException occurred during execution: {}", message, e);
+            throw new CommunicationException(message == null ? TEXT_OFFLINE_COMMUNICATION_ERROR : message,
+                    e.getCause());
+        } catch (TimeoutException e) {
+            String message = e.getMessage();
+            logger.debug("TimeoutException occurred during execution: {}", message, e);
+            throw new CommunicationException(message == null ? TEXT_OFFLINE_COMMUNICATION_ERROR : message);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            String message = e.getMessage();
+            logger.debug("InterruptedException occurred during execution: {}", message, e);
+            throw new CommunicationException(message == null ? TEXT_OFFLINE_COMMUNICATION_ERROR : message);
         }
     }
 
     private String getMessageError(String content) {
         final JsonObject json = JsonParser.parseString(content).getAsJsonObject();
-        final JsonElement errorsElement = json.get("errors");
+        final JsonElement errorsElement = json.get(JSON_VALUE_ERRORS);
         if (errorsElement != null && errorsElement.isJsonArray()) {
             return errorsElement.getAsJsonArray().toString();
         }
-        return "@text/offline.conf-error-unknown";
+        return TEXT_OFFLINE_CONF_ERROR_UNKNOWN;
     }
 
     private boolean getMessageStatus(String content) {
         final JsonObject json = JsonParser.parseString(content).getAsJsonObject();
-        return json.has("status") ? json.get("status").getAsInt() == 1 : false;
+        return json.has(JSON_VALUE_STATUS) ? json.get(JSON_VALUE_STATUS).getAsInt() == 1 : false;
     }
 
     private boolean getMessageStatus(JsonObject json) {
-        return json.has("status") ? json.get("status").getAsInt() == 1 : false;
+        return json.has(JSON_VALUE_STATUS) ? json.get(JSON_VALUE_STATUS).getAsInt() == 1 : false;
     }
 }
diff --git a/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/connection/PushoverCommunicationException.java b/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/connection/PushoverCommunicationException.java
deleted file mode 100644 (file)
index f6179f7..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * Copyright (c) 2010-2022 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.pushover.internal.connection;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-import org.eclipse.jdt.annotation.Nullable;
-
-/**
- * The {@link PushoverCommunicationException} is a configuration exception for the connections to Pushover Messages API.
- *
- * @author Christoph Weitkamp - Initial contribution
- */
-@NonNullByDefault
-public class PushoverCommunicationException extends RuntimeException {
-
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * Constructs a new exception with null as its detail message.
-     */
-    public PushoverCommunicationException() {
-        super();
-    }
-
-    /**
-     * Constructs a new exception with the specified detail message.
-     *
-     * @param message Detail message
-     */
-    public PushoverCommunicationException(@Nullable String message) {
-        super(message);
-    }
-
-    /**
-     * Constructs a new exception with the specified cause.
-     *
-     * @param cause The cause
-     */
-    public PushoverCommunicationException(@Nullable Throwable cause) {
-        super(cause);
-    }
-
-    /**
-     * Constructs a new exception with the specified detail message and cause.
-     *
-     * @param message Detail message
-     * @param cause The cause
-     */
-    public PushoverCommunicationException(@Nullable String message, @Nullable Throwable cause) {
-        super(message, cause);
-    }
-}
diff --git a/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/connection/PushoverConfigurationException.java b/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/connection/PushoverConfigurationException.java
deleted file mode 100644 (file)
index 8f48f6b..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * Copyright (c) 2010-2022 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.pushover.internal.connection;
-
-import org.eclipse.jdt.annotation.NonNullByDefault;
-
-/**
- * The {@link PushoverConfigurationException} is a configuration exception for the connections to Pushover Messages API.
- *
- * @author Christoph Weitkamp - Initial contribution
- */
-@NonNullByDefault
-public class PushoverConfigurationException extends IllegalArgumentException {
-
-    private static final long serialVersionUID = 1L;
-
-    /**
-     * Constructs a new exception with null as its detail message.
-     */
-    public PushoverConfigurationException() {
-        super();
-    }
-
-    /**
-     * Constructs a new exception with the specified detail message.
-     *
-     * @param message Detail message
-     */
-    public PushoverConfigurationException(String message) {
-        super(message);
-    }
-
-    /**
-     * Constructs a new exception with the specified cause.
-     *
-     * @param cause The cause
-     */
-    public PushoverConfigurationException(Throwable cause) {
-        super(cause);
-    }
-
-    /**
-     * Constructs a new exception with the specified detail message and cause.
-     *
-     * @param message Detail message
-     * @param cause The cause
-     */
-    public PushoverConfigurationException(String message, Throwable cause) {
-        super(message, cause);
-    }
-}
index 7bbea44b52b5f46876860e5a7832dab3769d97df..9046e16dec5e4b925a0b89ebd74aa79e73db0397 100644 (file)
@@ -12,6 +12,8 @@
  */
 package org.openhab.binding.pushover.internal.connection;
 
+import static org.openhab.binding.pushover.internal.PushoverBindingConstants.*;
+
 import java.io.File;
 import java.io.IOException;
 import java.nio.file.Files;
@@ -25,6 +27,8 @@ import org.eclipse.jetty.client.api.ContentProvider;
 import org.eclipse.jetty.client.util.MultiPartContentProvider;
 import org.eclipse.jetty.client.util.PathContentProvider;
 import org.eclipse.jetty.client.util.StringContentProvider;
+import org.openhab.core.i18n.CommunicationException;
+import org.openhab.core.i18n.ConfigurationException;
 import org.openhab.core.io.net.http.HttpUtil;
 import org.openhab.core.library.types.RawType;
 import org.slf4j.Logger;
@@ -83,19 +87,19 @@ public class PushoverMessageBuilder {
     private boolean html = false;
     private boolean monospace = false;
 
-    private PushoverMessageBuilder(String apikey, String user) throws PushoverConfigurationException {
+    private PushoverMessageBuilder(String apikey, String user) throws ConfigurationException {
         body.addFieldPart(MESSAGE_KEY_TOKEN, new StringContentProvider(apikey), null);
         body.addFieldPart(MESSAGE_KEY_USER, new StringContentProvider(user), null);
     }
 
     public static PushoverMessageBuilder getInstance(@Nullable String apikey, @Nullable String user)
-            throws PushoverConfigurationException {
-        if (apikey == null || apikey.isEmpty()) {
-            throw new PushoverConfigurationException("@text/offline.conf-error-missing-apikey");
+            throws ConfigurationException {
+        if (apikey == null || apikey.isBlank()) {
+            throw new ConfigurationException(TEXT_OFFLINE_CONF_ERROR_MISSING_APIKEY);
         }
 
-        if (user == null || user.isEmpty()) {
-            throw new PushoverConfigurationException("@text/offline.conf-error-missing-user");
+        if (user == null || user.isBlank()) {
+            throw new ConfigurationException(TEXT_OFFLINE_CONF_ERROR_MISSING_USER);
         }
 
         return new PushoverMessageBuilder(apikey, user);
@@ -166,7 +170,7 @@ public class PushoverMessageBuilder {
         return this;
     }
 
-    public ContentProvider build() throws PushoverCommunicationException {
+    public ContentProvider build() throws CommunicationException {
         if (message != null) {
             if (message.length() > MAX_MESSAGE_LENGTH) {
                 throw new IllegalArgumentException(String.format(
@@ -279,27 +283,24 @@ public class PushoverMessageBuilder {
         return body;
     }
 
-    private Path createTempFile(byte[] data) throws PushoverCommunicationException {
+    private Path createTempFile(byte[] data) throws CommunicationException {
         try {
             Path tmpFile = Files.createTempFile("pushover-", ".tmp");
             return Files.write(tmpFile, data);
         } catch (IOException e) {
-            logger.debug("IOException occurred while creating temp file - skip sending message: {}",
-                    e.getLocalizedMessage(), e);
-            throw new PushoverCommunicationException(
-                    String.format("Skip sending the message: %s", e.getLocalizedMessage()), e);
+            logger.debug("IOException occurred while creating temp file - skip sending the message: {}", e.getMessage(),
+                    e);
+            throw new CommunicationException(TEXT_ERROR_SKIP_SENDING_MESSAGE, e.getCause(), e.getLocalizedMessage());
         }
     }
 
-    private void addFilePart(Path path, @Nullable String contentType) throws PushoverCommunicationException {
+    private void addFilePart(Path path, @Nullable String contentType) throws CommunicationException {
         try {
             body.addFilePart(MESSAGE_KEY_ATTACHMENT, path.toFile().getName(),
                     new PathContentProvider(contentType == null ? DEFAULT_CONTENT_TYPE : contentType, path), null);
         } catch (IOException e) {
-            logger.debug("IOException occurred while adding content - skip sending message: {}",
-                    e.getLocalizedMessage(), e);
-            throw new PushoverCommunicationException(
-                    String.format("Skip sending the message: %s", e.getLocalizedMessage()), e);
+            logger.debug("IOException occurred while adding content - skip sending the message: {}", e.getMessage(), e);
+            throw new CommunicationException(TEXT_ERROR_SKIP_SENDING_MESSAGE, e.getCause(), e.getLocalizedMessage());
         }
     }
 }
index 3342fdcf1ceea01c50667b28ac82269e06140599..f80c38d1471693c3752c6644050bbcd7068e3f39 100644 (file)
@@ -12,7 +12,7 @@
  */
 package org.openhab.binding.pushover.internal.handler;
 
-import static org.openhab.binding.pushover.internal.PushoverBindingConstants.DEFAULT_SOUND;
+import static org.openhab.binding.pushover.internal.PushoverBindingConstants.*;
 
 import java.util.Collection;
 import java.util.List;
@@ -25,10 +25,10 @@ import org.openhab.binding.pushover.internal.actions.PushoverActions;
 import org.openhab.binding.pushover.internal.config.PushoverAccountConfiguration;
 import org.openhab.binding.pushover.internal.config.PushoverConfigOptionProvider;
 import org.openhab.binding.pushover.internal.connection.PushoverAPIConnection;
-import org.openhab.binding.pushover.internal.connection.PushoverCommunicationException;
-import org.openhab.binding.pushover.internal.connection.PushoverConfigurationException;
 import org.openhab.binding.pushover.internal.connection.PushoverMessageBuilder;
 import org.openhab.binding.pushover.internal.dto.Sound;
+import org.openhab.core.i18n.CommunicationException;
+import org.openhab.core.i18n.ConfigurationException;
 import org.openhab.core.thing.ChannelUID;
 import org.openhab.core.thing.Thing;
 import org.openhab.core.thing.ThingStatus;
@@ -69,15 +69,15 @@ public class PushoverAccountHandler extends BaseThingHandler {
 
         boolean configValid = true;
         final String apikey = config.apikey;
-        if (apikey == null || apikey.isEmpty()) {
+        if (apikey == null || apikey.isBlank()) {
             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
-                    "@text/offline.conf-error-missing-apikey");
+                    TEXT_OFFLINE_CONF_ERROR_MISSING_APIKEY);
             configValid = false;
         }
         final String user = config.user;
-        if (user == null || user.isEmpty()) {
+        if (user == null || user.isBlank()) {
             updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR,
-                    "@text/offline.conf-error-missing-user");
+                    TEXT_OFFLINE_CONF_ERROR_MISSING_USER);
             configValid = false;
         }
 
@@ -101,11 +101,16 @@ public class PushoverAccountHandler extends BaseThingHandler {
      */
     public List<Sound> getSounds() {
         try {
-            return connection != null ? connection.getSounds() : PushoverAccountConfiguration.DEFAULT_SOUNDS;
-        } catch (PushoverCommunicationException e) {
+            if (connection != null) {
+                List<Sound> sounds = connection.getSounds();
+                if (sounds != null) {
+                    return sounds;
+                }
+            }
+        } catch (CommunicationException e) {
             // do nothing, causing exception is already logged
-        } catch (PushoverConfigurationException e) {
-            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
+        } catch (ConfigurationException e) {
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getRawMessage());
         }
         return PushoverAccountConfiguration.DEFAULT_SOUNDS;
     }
@@ -143,10 +148,10 @@ public class PushoverAccountHandler extends BaseThingHandler {
         if (connection != null) {
             try {
                 return connection.sendMessage(messageBuilder);
-            } catch (PushoverCommunicationException e) {
+            } catch (CommunicationException e) {
                 // do nothing, causing exception is already logged
-            } catch (PushoverConfigurationException e) {
-                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
+            } catch (ConfigurationException e) {
+                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getRawMessage());
             }
             return false;
         } else {
@@ -158,10 +163,10 @@ public class PushoverAccountHandler extends BaseThingHandler {
         if (connection != null) {
             try {
                 return connection.sendPriorityMessage(messageBuilder);
-            } catch (PushoverCommunicationException e) {
+            } catch (CommunicationException e) {
                 // do nothing, causing exception is already logged
-            } catch (PushoverConfigurationException e) {
-                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
+            } catch (ConfigurationException e) {
+                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getRawMessage());
             }
             return "";
         } else {
@@ -173,10 +178,10 @@ public class PushoverAccountHandler extends BaseThingHandler {
         if (connection != null) {
             try {
                 return connection.cancelPriorityMessage(receipt);
-            } catch (PushoverCommunicationException e) {
+            } catch (CommunicationException e) {
                 // do nothing, causing exception is already logged
-            } catch (PushoverConfigurationException e) {
-                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
+            } catch (ConfigurationException e) {
+                updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getRawMessage());
             }
             return false;
         } else {
@@ -189,8 +194,8 @@ public class PushoverAccountHandler extends BaseThingHandler {
         try {
             connection.validateUser();
             updateStatus(ThingStatus.ONLINE);
-        } catch (PushoverCommunicationException | PushoverConfigurationException e) {
-            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getMessage());
+        } catch (CommunicationException | ConfigurationException e) {
+            updateStatus(ThingStatus.OFFLINE, ThingStatusDetail.CONFIGURATION_ERROR, e.getRawMessage());
         }
     }
 }
index 8b8adc2b42a45d2fde6af15f1148248b0e6b93b2..abc609c56ecae17d1fc182b847fa0d10d8594673 100644 (file)
@@ -32,9 +32,11 @@ thing-type.config.pushover.pushover-account.user.description = Your user key or
 
 # user defined messages
 
+offline.communication-error = An unexpected exception occurred during execution.
 offline.conf-error-missing-apikey = The 'apikey' parameter must be configured.
 offline.conf-error-missing-user = The 'user' parameter must be configured.
 offline.conf-error-unknown = An unknown error occurred.
+error.skip-sending-message = Skip sending the message: {0}.
 
 # actions
 
index 80cf0a25bbb519f4974b43856a362a15dc2bdb61..4aadf34aaa2656ab3b02cd56a824654a4198e863 100644 (file)
@@ -37,6 +37,7 @@ import org.openhab.core.thing.binding.ThingHandler;
  *
  * @author Christoph Weitkamp - Initial contribution
  */
+@NonNullByDefault
 @ExtendWith(MockitoExtension.class)
 @MockitoSettings(strictness = Strictness.WARN)
 public class PushoverActionsTest {
@@ -47,7 +48,6 @@ public class PushoverActionsTest {
     private static final String URL_TITLE = "Some Link";
     private static final String RECEIPT = "12345";
 
-    @NonNullByDefault
     private final ThingActions thingActionsStub = new ThingActions() {
         @Override
         public void setThingHandler(ThingHandler handler) {
@@ -59,9 +59,8 @@ public class PushoverActionsTest {
         }
     };
 
-    private @Mock PushoverAccountHandler mockPushoverAccountHandler;
-
-    private PushoverActions pushoverThingActions;
+    private @NonNullByDefault({}) @Mock PushoverAccountHandler mockPushoverAccountHandler;
+    private @NonNullByDefault({}) PushoverActions pushoverThingActions;
 
     @BeforeEach
     public void setUp() {