Panels error handling
This commit is contained in:
parent
ba343fbd98
commit
8a180c4c0e
@ -79,7 +79,7 @@ class HomeAssistant {
|
|||||||
_fetchCompleter.complete();
|
_fetchCompleter.complete();
|
||||||
if (!uiOnly) MobileAppIntegrationManager.checkAppRegistration();
|
if (!uiOnly) MobileAppIntegrationManager.checkAppRegistration();
|
||||||
} else {
|
} else {
|
||||||
_fetchCompleter.completeError(HAError("Mobile app component not found", actions: [HAErrorAction.tryAgain(), HAErrorAction(type: HAErrorActionType.URL ,title: "Help",url: "http://ha-client.app/docs#mobile-app-integration")]));
|
_fetchCompleter.completeError(HACException("Mobile app component not found", actions: [HAErrorAction.tryAgain(), HAErrorAction(type: HAErrorActionType.URL ,title: "Help",url: "http://ha-client.app/docs#mobile-app-integration")]));
|
||||||
}
|
}
|
||||||
}).catchError((e) {
|
}).catchError((e) {
|
||||||
_fetchCompleter.completeError(e);
|
_fetchCompleter.completeError(e);
|
||||||
@ -144,11 +144,11 @@ class HomeAssistant {
|
|||||||
var data = json.decode(sharedPrefs.getString('cached_config'));
|
var data = json.decode(sharedPrefs.getString('cached_config'));
|
||||||
_parseConfig(data);
|
_parseConfig(data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw HAError("Error getting config: $e");
|
throw HACException("Error getting config: $e");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await ConnectionManager().sendSocketMessage(type: "get_config").then((data) => _parseConfig(data)).catchError((e) {
|
await ConnectionManager().sendSocketMessage(type: "get_config").then((data) => _parseConfig(data)).catchError((e) {
|
||||||
throw HAError("Error getting config: $e");
|
throw HACException("Error getting config: $e");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -164,13 +164,13 @@ class HomeAssistant {
|
|||||||
var data = json.decode(sharedPrefs.getString('cached_states'));
|
var data = json.decode(sharedPrefs.getString('cached_states'));
|
||||||
_parseStates(data);
|
_parseStates(data);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
throw HAError("Error getting states: $e");
|
throw HACException("Error getting states: $e");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await ConnectionManager().sendSocketMessage(type: "get_states").then(
|
await ConnectionManager().sendSocketMessage(type: "get_states").then(
|
||||||
(data) => _parseStates(data)
|
(data) => _parseStates(data)
|
||||||
).catchError((e) {
|
).catchError((e) {
|
||||||
throw HAError("Error getting states: $e");
|
throw HACException("Error getting states: $e");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -209,7 +209,7 @@ class HomeAssistant {
|
|||||||
_rawLovelaceData = null;
|
_rawLovelaceData = null;
|
||||||
completer.complete();
|
completer.complete();
|
||||||
} else {
|
} else {
|
||||||
completer.completeError(HAError("Error getting lovelace config: $e"));
|
completer.completeError(HACException("Error getting lovelace config: $e"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return completer.future;
|
return completer.future;
|
||||||
@ -249,14 +249,17 @@ class HomeAssistant {
|
|||||||
Future _getPanels(SharedPreferences sharedPrefs) async {
|
Future _getPanels(SharedPreferences sharedPrefs) async {
|
||||||
if (sharedPrefs != null) {
|
if (sharedPrefs != null) {
|
||||||
try {
|
try {
|
||||||
var data = json.decode(sharedPrefs.getString('cached_panels'));
|
var data = json.decode(sharedPrefs.getString('cached_panels') ?? '{}');
|
||||||
_parsePanels(data);
|
_parsePanels(data);
|
||||||
} catch (e) {
|
} catch (e, stacktrace) {
|
||||||
throw HAError("Error getting panels list: $e");
|
Crashlytics.instance.recordError(e, stacktrace);
|
||||||
|
panels.clear();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await ConnectionManager().sendSocketMessage(type: "get_panels").then((data) => _parsePanels(data)).catchError((e) {
|
await ConnectionManager().sendSocketMessage(type: "get_panels").then((data) => _parsePanels(data)).catchError((e, stacktrace) {
|
||||||
throw HAError("Error getting panels list: $e");
|
panels.clear();
|
||||||
|
Crashlytics.instance.recordError(e, stacktrace);
|
||||||
|
throw HACException('Can\'t get panles: $e');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ class AuthManager {
|
|||||||
}).catchError((e) {
|
}).catchError((e) {
|
||||||
Logger.e("Error getting temp token: ${e.toString()}");
|
Logger.e("Error getting temp token: ${e.toString()}");
|
||||||
eventBus.fire(StartAuthEvent(oauthUrl, false));
|
eventBus.fire(StartAuthEvent(oauthUrl, false));
|
||||||
completer.completeError(HAError("Error getting temp token"));
|
completer.completeError(HACException("Error getting temp token"));
|
||||||
}).whenComplete(() => flutterWebviewPlugin.close());
|
}).whenComplete(() => flutterWebviewPlugin.close());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -53,7 +53,7 @@ class ConnectionManager {
|
|||||||
Logger.d('$_domain$_port');
|
Logger.d('$_domain$_port');
|
||||||
if ((_domain == null) || (_port == null) ||
|
if ((_domain == null) || (_port == null) ||
|
||||||
(_domain.isEmpty) || (_port.isEmpty)) {
|
(_domain.isEmpty) || (_port.isEmpty)) {
|
||||||
completer.completeError(HAError.checkConnectionSettings());
|
completer.completeError(HACException.checkConnectionSettings());
|
||||||
stopInit = true;
|
stopInit = true;
|
||||||
} else {
|
} else {
|
||||||
final storage = new FlutterSecureStorage();
|
final storage = new FlutterSecureStorage();
|
||||||
@ -66,7 +66,7 @@ class ConnectionManager {
|
|||||||
'https://ha-client.app/service/auth_callback.html')}";
|
'https://ha-client.app/service/auth_callback.html')}";
|
||||||
settingsLoaded = true;
|
settingsLoaded = true;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
completer.completeError(HAError("Error reading login details", actions: [HAErrorAction.tryAgain(type: HAErrorActionType.FULL_RELOAD), HAErrorAction.loginAgain()]));
|
completer.completeError(HACException("Error reading login details", actions: [HAErrorAction.tryAgain(type: HAErrorActionType.FULL_RELOAD), HAErrorAction.loginAgain()]));
|
||||||
Logger.e("Cannt read secure storage. Need to relogin.");
|
Logger.e("Cannt read secure storage. Need to relogin.");
|
||||||
stopInit = true;
|
stopInit = true;
|
||||||
}
|
}
|
||||||
@ -74,7 +74,7 @@ class ConnectionManager {
|
|||||||
} else {
|
} else {
|
||||||
if ((_domain == null) || (_port == null) ||
|
if ((_domain == null) || (_port == null) ||
|
||||||
(_domain.isEmpty) || (_port.isEmpty)) {
|
(_domain.isEmpty) || (_port.isEmpty)) {
|
||||||
completer.completeError(HAError.checkConnectionSettings());
|
completer.completeError(HACException.checkConnectionSettings());
|
||||||
stopInit = true;
|
stopInit = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -107,13 +107,13 @@ class ConnectionManager {
|
|||||||
_disconnect().then((_) {
|
_disconnect().then((_) {
|
||||||
if (e is TimeoutException) {
|
if (e is TimeoutException) {
|
||||||
if (connecting != null && !connecting.isCompleted) {
|
if (connecting != null && !connecting.isCompleted) {
|
||||||
connecting.completeError(HAError("Connection timeout"));
|
connecting.completeError(HACException("Connection timeout"));
|
||||||
}
|
}
|
||||||
completer?.completeError(HAError("Connection timeout"));
|
completer?.completeError(HACException("Connection timeout"));
|
||||||
} else if (e is HAError) {
|
} else if (e is HACException) {
|
||||||
completer?.completeError(e);
|
completer?.completeError(e);
|
||||||
} else {
|
} else {
|
||||||
completer?.completeError(HAError("${e.toString()}"));
|
completer?.completeError(HACException("${e.toString()}"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -167,9 +167,9 @@ class ConnectionManager {
|
|||||||
});
|
});
|
||||||
} else if (data["type"] == "auth_invalid") {
|
} else if (data["type"] == "auth_invalid") {
|
||||||
Logger.d("[Received] <== ${data.toString()}");
|
Logger.d("[Received] <== ${data.toString()}");
|
||||||
_messageResolver["auth"]?.completeError(HAError("${data["message"]}", actions: [HAErrorAction.loginAgain()]));
|
_messageResolver["auth"]?.completeError(HACException("${data["message"]}", actions: [HAErrorAction.loginAgain()]));
|
||||||
_messageResolver.remove("auth");
|
_messageResolver.remove("auth");
|
||||||
if (!connecting.isCompleted) connecting.completeError(HAError("${data["message"]}", actions: [HAErrorAction.tryAgain(title: "Retry"), HAErrorAction.loginAgain(title: "Relogin")]));
|
if (!connecting.isCompleted) connecting.completeError(HACException("${data["message"]}", actions: [HAErrorAction.tryAgain(title: "Retry"), HAErrorAction.loginAgain(title: "Relogin")]));
|
||||||
} else {
|
} else {
|
||||||
_handleMessage(data);
|
_handleMessage(data);
|
||||||
}
|
}
|
||||||
@ -179,7 +179,7 @@ class ConnectionManager {
|
|||||||
onError: (e) => _handleSocketError(e, connecting)
|
onError: (e) => _handleSocketError(e, connecting)
|
||||||
);
|
);
|
||||||
} catch(exeption) {
|
} catch(exeption) {
|
||||||
connecting.completeError(HAError("${exeption.toString()}"));
|
connecting.completeError(HACException("${exeption.toString()}"));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return connecting.future;
|
return connecting.future;
|
||||||
@ -213,7 +213,7 @@ class ConnectionManager {
|
|||||||
_messageResolver["${data["id"]}"]?.complete(data["result"]);
|
_messageResolver["${data["id"]}"]?.complete(data["result"]);
|
||||||
} else if (data["id"] != null) {
|
} else if (data["id"] != null) {
|
||||||
Logger.e("[Received] <== Error received on request id ${data['id']}: ${data['error']}");
|
Logger.e("[Received] <== Error received on request id ${data['id']}: ${data['error']}");
|
||||||
_messageResolver["${data["id"]}"]?.completeError("${data["error"]["code"]}");
|
_messageResolver["${data["id"]}"]?.completeError("${data["error"]["code"]}: ${data["error"]["message"]}");
|
||||||
}
|
}
|
||||||
_messageResolver.remove("${data["id"]}");
|
_messageResolver.remove("${data["id"]}");
|
||||||
} else if (data["type"] == "event") {
|
} else if (data["type"] == "event") {
|
||||||
@ -236,9 +236,9 @@ class ConnectionManager {
|
|||||||
_disconnect().then((_) {
|
_disconnect().then((_) {
|
||||||
if (!connectionCompleter.isCompleted) {
|
if (!connectionCompleter.isCompleted) {
|
||||||
isConnected = false;
|
isConnected = false;
|
||||||
connectionCompleter.completeError(HAError("Disconnected", actions: [HAErrorAction.reconnect()]));
|
connectionCompleter.completeError(HACException("Disconnected", actions: [HAErrorAction.reconnect()]));
|
||||||
}
|
}
|
||||||
eventBus.fire(ShowErrorEvent(HAError("Unable to connect to Home Assistant")));
|
eventBus.fire(ShowErrorEvent(HACException("Unable to connect to Home Assistant")));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,9 +247,9 @@ class ConnectionManager {
|
|||||||
_disconnect().then((_) {
|
_disconnect().then((_) {
|
||||||
if (!connectionCompleter.isCompleted) {
|
if (!connectionCompleter.isCompleted) {
|
||||||
isConnected = false;
|
isConnected = false;
|
||||||
connectionCompleter.completeError(HAError("Disconnected", actions: [HAErrorAction.reconnect()]));
|
connectionCompleter.completeError(HACException("Disconnected", actions: [HAErrorAction.reconnect()]));
|
||||||
}
|
}
|
||||||
eventBus.fire(ShowErrorEvent(HAError("Unable to connect to Home Assistant")));
|
eventBus.fire(ShowErrorEvent(HACException("Unable to connect to Home Assistant")));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,7 +282,7 @@ class ConnectionManager {
|
|||||||
});
|
});
|
||||||
}).catchError((e) => completer.completeError(e));
|
}).catchError((e) => completer.completeError(e));
|
||||||
} else {
|
} else {
|
||||||
completer.completeError(HAError("General login error"));
|
completer.completeError(HACException("General login error"));
|
||||||
}
|
}
|
||||||
return completer.future;
|
return completer.future;
|
||||||
}
|
}
|
||||||
@ -317,7 +317,7 @@ class ConnectionManager {
|
|||||||
throw e;
|
throw e;
|
||||||
});
|
});
|
||||||
}).catchError((e) {
|
}).catchError((e) {
|
||||||
completer.completeError(HAError("Authentication error: $e", actions: [HAErrorAction.reload(title: "Retry"), HAErrorAction.loginAgain(title: "Relogin")]));
|
completer.completeError(HACException("Authentication error: $e", actions: [HAErrorAction.reload(title: "Retry"), HAErrorAction.loginAgain(title: "Relogin")]));
|
||||||
});
|
});
|
||||||
return completer.future;
|
return completer.future;
|
||||||
}
|
}
|
||||||
@ -344,7 +344,7 @@ class ConnectionManager {
|
|||||||
_socket.sink.add(rawMessage);
|
_socket.sink.add(rawMessage);
|
||||||
}).catchError((e) {
|
}).catchError((e) {
|
||||||
if (!_completer.isCompleted) {
|
if (!_completer.isCompleted) {
|
||||||
_completer.completeError(HAError("No connection to Home Assistant", actions: [HAErrorAction.reconnect()]));
|
_completer.completeError(HACException("No connection to Home Assistant", actions: [HAErrorAction.reconnect()]));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -373,12 +373,12 @@ class ConnectionManager {
|
|||||||
sendHTTPPost(
|
sendHTTPPost(
|
||||||
endPoint: "/api/services/$domain/$service",
|
endPoint: "/api/services/$domain/$service",
|
||||||
data: json.encode(serviceData)
|
data: json.encode(serviceData)
|
||||||
).then((data) => completer.complete(data)).catchError((e) => completer.completeError(HAError(e.toString())));
|
).then((data) => completer.complete(data)).catchError((e) => completer.completeError(HACException(e.toString())));
|
||||||
//return sendSocketMessage(type: "call_service", additionalData: {"domain": domain, "service": service, "service_data": serviceData});
|
//return sendSocketMessage(type: "call_service", additionalData: {"domain": domain, "service": service, "service_data": serviceData});
|
||||||
else
|
else
|
||||||
sendHTTPPost(
|
sendHTTPPost(
|
||||||
endPoint: "/api/services/$domain/$service"
|
endPoint: "/api/services/$domain/$service"
|
||||||
).then((data) => completer.complete(data)).catchError((e) => completer.completeError(HAError(e.toString())));
|
).then((data) => completer.complete(data)).catchError((e) => completer.completeError(HACException(e.toString())));
|
||||||
//return sendSocketMessage(type: "call_service", additionalData: {"domain": domain, "service": service});
|
//return sendSocketMessage(type: "call_service", additionalData: {"domain": domain, "service": service});
|
||||||
return completer.future;
|
return completer.future;
|
||||||
}
|
}
|
||||||
|
@ -131,10 +131,10 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
|||||||
});
|
});
|
||||||
HomeAssistant().saveCache();
|
HomeAssistant().saveCache();
|
||||||
}).catchError((e) {
|
}).catchError((e) {
|
||||||
if (e is HAError) {
|
if (e is HACException) {
|
||||||
_setErrorState(e);
|
_setErrorState(e);
|
||||||
} else {
|
} else {
|
||||||
_setErrorState(HAError(e.toString()));
|
_setErrorState(HACException(e.toString()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
eventBus.fire(RefreshDataFinishedEvent());
|
eventBus.fire(RefreshDataFinishedEvent());
|
||||||
@ -254,10 +254,10 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
|||||||
Navigator.of(context).pushNamed("/auth", arguments: {"url": ConnectionManager().oauthUrl});
|
Navigator.of(context).pushNamed("/auth", arguments: {"url": ConnectionManager().oauthUrl});
|
||||||
}
|
}
|
||||||
|
|
||||||
_setErrorState(HAError e) {
|
_setErrorState(HACException e) {
|
||||||
if (e == null) {
|
if (e == null) {
|
||||||
_bottomInfoBarController.showErrorBottomBar(
|
_bottomInfoBarController.showErrorBottomBar(
|
||||||
HAError("Unknown error")
|
HACException("Unknown error")
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
_bottomInfoBarController.showErrorBottomBar(e);
|
_bottomInfoBarController.showErrorBottomBar(e);
|
||||||
|
@ -40,12 +40,12 @@ class BottomInfoBarController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void showErrorBottomBar(HAError error) {
|
void showErrorBottomBar(HACException error) {
|
||||||
actions.clear();
|
actions.clear();
|
||||||
actions.addAll(error.actions);
|
actions.addAll(error.actions);
|
||||||
bottomBarErrorColor = true;
|
bottomBarErrorColor = true;
|
||||||
bottomBarProgress = false;
|
bottomBarProgress = false;
|
||||||
bottomBarText = "${error.message}";
|
bottomBarText = "${error.cause}";
|
||||||
if (show == null) {
|
if (show == null) {
|
||||||
initialState = true;
|
initialState = true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -24,7 +24,7 @@ class Panel {
|
|||||||
icon = Panel.iconsByComponent[componentName];
|
icon = Panel.iconsByComponent[componentName];
|
||||||
}
|
}
|
||||||
isHidden = (componentName == 'kiosk' || componentName == 'states' || componentName == 'profile' || componentName == 'developer-tools');
|
isHidden = (componentName == 'kiosk' || componentName == 'states' || componentName == 'profile' || componentName == 'developer-tools');
|
||||||
isWebView = (componentName != 'config' && componentName != 'lovelace' && !componentName.startsWith('haclient'));
|
isWebView = (componentName != 'lovelace' && !componentName.startsWith('haclient'));
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleOpen(BuildContext context) {
|
void handleOpen(BuildContext context) {
|
||||||
@ -68,10 +68,6 @@ class Panel {
|
|||||||
|
|
||||||
Widget getWidget() {
|
Widget getWidget() {
|
||||||
switch (componentName) {
|
switch (componentName) {
|
||||||
case "config": {
|
|
||||||
return ConfigPanelWidget();
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
return Text("Unsupported panel component: $componentName");
|
return Text("Unsupported panel component: $componentName");
|
||||||
}
|
}
|
||||||
|
@ -90,7 +90,7 @@ class ShowPageEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ShowErrorEvent {
|
class ShowErrorEvent {
|
||||||
final HAError error;
|
final HACException error;
|
||||||
|
|
||||||
ShowErrorEvent(this.error);
|
ShowErrorEvent(this.error);
|
||||||
}
|
}
|
@ -1,21 +1,26 @@
|
|||||||
part of '../main.dart';
|
part of '../main.dart';
|
||||||
|
|
||||||
class HAError {
|
class HACException implements Exception {
|
||||||
String message;
|
String cause;
|
||||||
final List<HAErrorAction> actions;
|
final List<HAErrorAction> actions;
|
||||||
|
|
||||||
HAError(this.message, {this.actions: const [HAErrorAction.tryAgain()]});
|
HACException(this.cause, {this.actions: const [HAErrorAction.tryAgain()]});
|
||||||
|
|
||||||
HAError.unableToConnect({this.actions = const [HAErrorAction.tryAgain()]}) {
|
HACException.unableToConnect({this.actions = const [HAErrorAction.tryAgain()]}) {
|
||||||
this.message = "Unable to connect to Home Assistant";
|
this.cause = "Unable to connect to Home Assistant";
|
||||||
}
|
}
|
||||||
|
|
||||||
HAError.disconnected({this.actions = const [HAErrorAction.reconnect()]}) {
|
HACException.disconnected({this.actions = const [HAErrorAction.reconnect()]}) {
|
||||||
this.message = "Disconnected";
|
this.cause = "Disconnected";
|
||||||
}
|
}
|
||||||
|
|
||||||
HAError.checkConnectionSettings({this.actions = const [HAErrorAction.reload(), HAErrorAction(title: "Settings", type: HAErrorActionType.OPEN_CONNECTION_SETTINGS)]}) {
|
HACException.checkConnectionSettings({this.actions = const [HAErrorAction.reload(), HAErrorAction(title: "Settings", type: HAErrorActionType.OPEN_CONNECTION_SETTINGS)]}) {
|
||||||
this.message = "Check connection settings";
|
this.cause = "Check connection settings";
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'HACException: $cause';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user