]> git.basschouten.com Git - openhab-addons.git/blob
3a7294b56a482d0e8264c1d8e4a2a1640fcddbc2
[openhab-addons.git] /
1 /**
2  * Copyright (c) 2010-2022 Contributors to the openHAB project
3  *
4  * See the NOTICE file(s) distributed with this work for additional
5  * information.
6  *
7  * This program and the accompanying materials are made available under the
8  * terms of the Eclipse Public License 2.0 which is available at
9  * http://www.eclipse.org/legal/epl-2.0
10  *
11  * SPDX-License-Identifier: EPL-2.0
12  */
13 package org.openhab.binding.shelly.internal.api;
14
15 import java.net.ConnectException;
16 import java.net.MalformedURLException;
17 import java.net.NoRouteToHostException;
18 import java.net.PortUnreachableException;
19 import java.net.SocketException;
20 import java.net.SocketTimeoutException;
21 import java.net.UnknownHostException;
22 import java.text.MessageFormat;
23 import java.util.concurrent.ExecutionException;
24 import java.util.concurrent.TimeoutException;
25
26 import org.eclipse.jdt.annotation.NonNullByDefault;
27 import org.eclipse.jdt.annotation.Nullable;
28
29 import com.google.gson.JsonSyntaxException;
30
31 /**
32  * The {@link CarNetException} implements an extension to the standard Exception class. This allows to keep also the
33  * result of the last API call (e.g. including the http status code in the message).
34  *
35  * @author Markus Michels - Initial contribution
36  */
37 @NonNullByDefault
38 public class ShellyApiException extends Exception {
39     private static final long serialVersionUID = -5809459454769761821L;
40
41     private ShellyApiResult apiResult = new ShellyApiResult();
42     private static final String NONE = "none";
43
44     public ShellyApiException(Exception exception) {
45         super(exception);
46     }
47
48     public ShellyApiException(String message) {
49         super(message);
50     }
51
52     public ShellyApiException(ShellyApiResult res) {
53         super(NONE);
54         apiResult = res;
55     }
56
57     public ShellyApiException(String message, Exception exception) {
58         super(message, exception);
59     }
60
61     public ShellyApiException(ShellyApiResult result, Exception exception) {
62         super(exception);
63         apiResult = result;
64     }
65
66     @Override
67     public @Nullable String getMessage() {
68         return isEmpty() ? "" : nonNullString(super.getMessage());
69     }
70
71     @Override
72     public String toString() {
73         String message = nonNullString(super.getMessage()).replace("java.util.concurrent.ExecutionException: ", "")
74                 .replace("java.net.", "");
75         String cause = getCauseClass().toString();
76         String url = apiResult.getUrl();
77         if (!isEmpty()) {
78             if (isUnknownHost()) {
79                 String[] string = message.split(": "); // java.net.UnknownHostException: api.rach.io
80                 message = MessageFormat.format("Unable to connect to {0} (Unknown host / Network down / Low signal)",
81                         string[1]);
82             } else if (isMalformedURL()) {
83                 message = "Invalid URL: " + url;
84             } else if (isTimeout()) {
85                 message = "API Timeout for " + url;
86             } else if (!isConnectionError()) {
87                 message = message + "(" + cause + ")";
88             }
89         } else {
90             message = apiResult.toString();
91         }
92         return message;
93     }
94
95     public boolean isApiException() {
96         return getCauseClass() == ShellyApiException.class;
97     }
98
99     public boolean isTimeout() {
100         Class<?> extype = !isEmpty() ? getCauseClass() : null;
101         return (extype != null) && ((extype == TimeoutException.class) || extype == InterruptedException.class
102                 || extype == SocketTimeoutException.class
103                 || nonNullString(getMessage()).toLowerCase().contains("timeout"));
104     }
105
106     public boolean isConnectionError() {
107         Class<?> exType = getCauseClass();
108         return isUnknownHost() || isMalformedURL() || exType == ConnectException.class
109                 || exType == SocketException.class || exType == PortUnreachableException.class
110                 || exType == NoRouteToHostException.class;
111     }
112
113     public boolean isUnknownHost() {
114         return getCauseClass() == UnknownHostException.class;
115     }
116
117     public boolean isMalformedURL() {
118         return getCauseClass() == MalformedURLException.class;
119     }
120
121     public boolean isHttpAccessUnauthorized() {
122         return apiResult.isHttpAccessUnauthorized();
123     }
124
125     public boolean isJSONException() {
126         return getCauseClass() == JsonSyntaxException.class;
127     }
128
129     public ShellyApiResult getApiResult() {
130         return apiResult;
131     }
132
133     private boolean isEmpty() {
134         return NONE.equals(nonNullString(super.getMessage()));
135     }
136
137     private static String nonNullString(@Nullable String s) {
138         return s != null ? s : "";
139     }
140
141     private Class<?> getCauseClass() {
142         Throwable cause = getCause();
143         if (cause != null && cause.getClass() == ExecutionException.class) {
144             cause = cause.getCause();
145         }
146         if (cause != null) {
147             return cause.getClass();
148         }
149         return ShellyApiException.class;
150     }
151 }