From 8b3bb313eb229304b061c65a9da0ae51bed86ab8 Mon Sep 17 00:00:00 2001 From: Christoph Weitkamp Date: Sun, 16 Jan 2022 18:07:36 +0100 Subject: [PATCH] [pushover] Improved exception handling (#12023) * Improved exception handling Signed-off-by: Christoph Weitkamp --- .../internal/PushoverBindingConstants.java | 6 + .../connection/PushoverAPIConnection.java | 107 +++++++++++------- .../PushoverCommunicationException.java | 62 ---------- .../PushoverConfigurationException.java | 61 ---------- .../connection/PushoverMessageBuilder.java | 35 +++--- .../handler/PushoverAccountHandler.java | 49 ++++---- .../resources/OH-INF/i18n/pushover.properties | 2 + .../internal/actions/PushoverActionsTest.java | 7 +- 8 files changed, 119 insertions(+), 210 deletions(-) delete mode 100644 bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/connection/PushoverCommunicationException.java delete mode 100644 bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/connection/PushoverConfigurationException.java diff --git a/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/PushoverBindingConstants.java b/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/PushoverBindingConstants.java index f3a31c15c1f66..28231c407a2b3 100644 --- a/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/PushoverBindingConstants.java +++ b/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/PushoverBindingConstants.java @@ -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"; } diff --git a/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/connection/PushoverAPIConnection.java b/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/connection/PushoverAPIConnection.java index 5f29b28118219..2c9d756381a5d 100644 --- a/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/connection/PushoverAPIConnection.java +++ b/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/connection/PushoverAPIConnection.java @@ -12,9 +12,10 @@ */ 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.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 @@ @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 cache = new ExpiringCacheMap<>(TimeUnit.DAYS.toMillis(1)); + private final ExpiringCache> 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 getSounds() throws PushoverCommunicationException, PushoverConfigurationException { + public @Nullable List getSounds() { + return cache.getValue(); + } + + private List 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 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 requestParams) { @@ -115,21 +131,16 @@ private String encodeParam(@Nullable String value) { 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 @@ private synchronized String executeRequest(HttpMethod httpMethod, String url, @N 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 index f6179f744b697..0000000000000 --- a/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/connection/PushoverCommunicationException.java +++ /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 index 8f48f6b896963..0000000000000 --- a/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/connection/PushoverConfigurationException.java +++ /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); - } -} diff --git a/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/connection/PushoverMessageBuilder.java b/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/connection/PushoverMessageBuilder.java index 7bbea44b52b5f..9046e16dec5e4 100644 --- a/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/connection/PushoverMessageBuilder.java +++ b/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/connection/PushoverMessageBuilder.java @@ -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.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 PushoverMessageBuilder withMonospaceFormatting() { 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 ContentProvider build() throws PushoverCommunicationException { 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()); } } } diff --git a/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/handler/PushoverAccountHandler.java b/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/handler/PushoverAccountHandler.java index 3342fdcf1ceea..f80c38d147169 100644 --- a/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/handler/PushoverAccountHandler.java +++ b/bundles/org.openhab.binding.pushover/src/main/java/org/openhab/binding/pushover/internal/handler/PushoverAccountHandler.java @@ -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.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 void initialize() { 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 Collection> getServices() { */ public List getSounds() { try { - return connection != null ? connection.getSounds() : PushoverAccountConfiguration.DEFAULT_SOUNDS; - } catch (PushoverCommunicationException e) { + if (connection != null) { + List 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 boolean sendMessage(PushoverMessageBuilder messageBuilder) { 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 String sendPriorityMessage(PushoverMessageBuilder messageBuilder) { 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 boolean cancelPriorityMessage(String receipt) { 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 @@ private void asyncValidateUser() { 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()); } } } diff --git a/bundles/org.openhab.binding.pushover/src/main/resources/OH-INF/i18n/pushover.properties b/bundles/org.openhab.binding.pushover/src/main/resources/OH-INF/i18n/pushover.properties index 8b8adc2b42a45..abc609c56ecae 100644 --- a/bundles/org.openhab.binding.pushover/src/main/resources/OH-INF/i18n/pushover.properties +++ b/bundles/org.openhab.binding.pushover/src/main/resources/OH-INF/i18n/pushover.properties @@ -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 diff --git a/bundles/org.openhab.binding.pushover/src/test/java/org/openhab/binding/pushover/internal/actions/PushoverActionsTest.java b/bundles/org.openhab.binding.pushover/src/test/java/org/openhab/binding/pushover/internal/actions/PushoverActionsTest.java index 80cf0a25bbb51..4aadf34aaa265 100644 --- a/bundles/org.openhab.binding.pushover/src/test/java/org/openhab/binding/pushover/internal/actions/PushoverActionsTest.java +++ b/bundles/org.openhab.binding.pushover/src/test/java/org/openhab/binding/pushover/internal/actions/PushoverActionsTest.java @@ -37,6 +37,7 @@ * * @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 void setThingHandler(ThingHandler handler) { } }; - private @Mock PushoverAccountHandler mockPushoverAccountHandler; - - private PushoverActions pushoverThingActions; + private @NonNullByDefault({}) @Mock PushoverAccountHandler mockPushoverAccountHandler; + private @NonNullByDefault({}) PushoverActions pushoverThingActions; @BeforeEach public void setUp() {