New error class
This commit is contained in:
@ -33,7 +33,7 @@ class AuthManager {
|
|||||||
flutterWebviewPlugin.close();
|
flutterWebviewPlugin.close();
|
||||||
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({"errorCode": 61, "errorMessage": "Error getting temp token"});
|
completer.completeError(HAError("Error getting temp token"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -63,7 +63,7 @@ class Connection {
|
|||||||
}
|
}
|
||||||
if ((_domain == null) || (_port == null) ||
|
if ((_domain == null) || (_port == null) ||
|
||||||
(_domain.isEmpty) || (_port.isEmpty)) {
|
(_domain.isEmpty) || (_port.isEmpty)) {
|
||||||
completer.completeError({"errorCode": 5, "errorMessage": "Check connection settings"});
|
completer.completeError(HAError.checkConnectionSettings());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_token == null) {
|
if (_token == null) {
|
||||||
@ -87,8 +87,7 @@ class Connection {
|
|||||||
if (forceReconnect || !isConnected) {
|
if (forceReconnect || !isConnected) {
|
||||||
_connect().timeout(connectTimeout, onTimeout: () {
|
_connect().timeout(connectTimeout, onTimeout: () {
|
||||||
_disconnect().then((_) {
|
_disconnect().then((_) {
|
||||||
completer?.completeError(
|
completer?.completeError(HAError("Connection timeout"));
|
||||||
{"errorCode": 1, "errorMessage": "Connection timeout"});
|
|
||||||
});
|
});
|
||||||
}).then((_) => completer?.complete()).catchError((e) {
|
}).then((_) => completer?.complete()).catchError((e) {
|
||||||
completer?.completeError(e);
|
completer?.completeError(e);
|
||||||
@ -127,12 +126,10 @@ class Connection {
|
|||||||
if (!connecting.isCompleted) connecting.complete();
|
if (!connecting.isCompleted) connecting.complete();
|
||||||
} 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(
|
_messageResolver["auth"]?.completeError(HAError("${data["message"]}", actions: [HAErrorAction.loginAgain()]));
|
||||||
{"errorCode": 62, "errorMessage": "${data["message"]}"});
|
|
||||||
_messageResolver.remove("auth");
|
_messageResolver.remove("auth");
|
||||||
logout().then((_) {
|
logout().then((_) {
|
||||||
if (!connecting.isCompleted) connecting.completeError(
|
if (!connecting.isCompleted) connecting.completeError(HAError("${data["message"]}", actions: [HAErrorAction.loginAgain()]));
|
||||||
{"errorCode": 62, "errorMessage": "${data["message"]}"});
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
_handleMessage(data);
|
_handleMessage(data);
|
||||||
@ -146,6 +143,8 @@ class Connection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Future _disconnect() {
|
Future _disconnect() {
|
||||||
Completer completer = Completer();
|
Completer completer = Completer();
|
||||||
if (!isConnected) {
|
if (!isConnected) {
|
||||||
@ -173,7 +172,7 @@ class Connection {
|
|||||||
_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({"errorMessage": "${data['error']["message"]}"});
|
_messageResolver["${data["id"]}"]?.completeError("${data['error']["message"]}");
|
||||||
}
|
}
|
||||||
_messageResolver.remove("${data["id"]}");
|
_messageResolver.remove("${data["id"]}");
|
||||||
} else if (data["type"] == "event") {
|
} else if (data["type"] == "event") {
|
||||||
@ -194,14 +193,14 @@ class Connection {
|
|||||||
Logger.d("Socket disconnected.");
|
Logger.d("Socket disconnected.");
|
||||||
if (!connectionCompleter.isCompleted) {
|
if (!connectionCompleter.isCompleted) {
|
||||||
isConnected = false;
|
isConnected = false;
|
||||||
connectionCompleter.completeError({"errorCode": 82, "errorMessage": "Disconnected"});
|
connectionCompleter.completeError(HAError("Disconnected", actions: [HAErrorAction.reconnect()]));
|
||||||
} else {
|
} else {
|
||||||
_disconnect().then((_) {
|
_disconnect().then((_) {
|
||||||
Timer(Duration(seconds: 5), () {
|
Timer(Duration(seconds: 5), () {
|
||||||
Logger.d("Trying to reconnect...");
|
Logger.d("Trying to reconnect...");
|
||||||
_connect().catchError((e) {
|
_connect().catchError((e) {
|
||||||
isConnected = false;
|
isConnected = false;
|
||||||
eventBus.fire(ShowErrorEvent("Unable to connect to Home Assistant", 81));
|
eventBus.fire(ShowErrorEvent(HAError("Unable to connect to Home Assistant")));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -212,14 +211,14 @@ class Connection {
|
|||||||
Logger.e("Socket stream Error: $e");
|
Logger.e("Socket stream Error: $e");
|
||||||
if (!connectionCompleter.isCompleted) {
|
if (!connectionCompleter.isCompleted) {
|
||||||
isConnected = false;
|
isConnected = false;
|
||||||
connectionCompleter.completeError({"errorCode": 81, "errorMessage": "Unable to connect to Home Assistant"});
|
connectionCompleter.completeError(HAError("Unable to connect to Home Assistant"));
|
||||||
} else {
|
} else {
|
||||||
_disconnect().then((_) {
|
_disconnect().then((_) {
|
||||||
Timer(Duration(seconds: 5), () {
|
Timer(Duration(seconds: 5), () {
|
||||||
Logger.d("Trying to reconnect...");
|
Logger.d("Trying to reconnect...");
|
||||||
_connect().catchError((e) {
|
_connect().catchError((e) {
|
||||||
isConnected = false;
|
isConnected = false;
|
||||||
eventBus.fire(ShowErrorEvent("Unable to connect to Home Assistant", 81));
|
eventBus.fire(ShowErrorEvent(HAError("Unable to connect to Home Assistant")));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -254,7 +253,7 @@ class Connection {
|
|||||||
});
|
});
|
||||||
}).catchError((e) => completer.completeError(e));
|
}).catchError((e) => completer.completeError(e));
|
||||||
} else {
|
} else {
|
||||||
completer.completeError({"errorCode": 63, "errorMessage": "General login error"});
|
completer.completeError(HAError("General login error"));
|
||||||
}
|
}
|
||||||
return completer.future;
|
return completer.future;
|
||||||
}
|
}
|
||||||
@ -286,7 +285,7 @@ class Connection {
|
|||||||
});
|
});
|
||||||
}).catchError((e) {
|
}).catchError((e) {
|
||||||
logout();
|
logout();
|
||||||
completer.completeError({"errorCode": 63, "errorMessage": "Authentication error: $e"});
|
completer.completeError(HAError("Authentication error: $e", actions: [HAErrorAction.loginAgain()]));
|
||||||
});
|
});
|
||||||
return completer.future;
|
return completer.future;
|
||||||
}
|
}
|
||||||
@ -309,7 +308,7 @@ class Connection {
|
|||||||
String rawMessage = json.encode(dataObject);
|
String rawMessage = json.encode(dataObject);
|
||||||
if (!isConnected) {
|
if (!isConnected) {
|
||||||
_connect().timeout(connectTimeout, onTimeout: (){
|
_connect().timeout(connectTimeout, onTimeout: (){
|
||||||
_completer.completeError({"errorCode": 8, "errorMessage": "No connection to Home Assistant"});
|
_completer.completeError(HAError("No connection to Home Assistant", actions: [HAErrorAction.reconnect()]));
|
||||||
}).then((_) {
|
}).then((_) {
|
||||||
Logger.d("[Sending] ==> $rawMessage");
|
Logger.d("[Sending] ==> $rawMessage");
|
||||||
_socket.sink.add(rawMessage);
|
_socket.sink.add(rawMessage);
|
||||||
|
@ -54,8 +54,12 @@ class HomeAssistant {
|
|||||||
additionalData: {"event_type": "state_changed"},
|
additionalData: {"event_type": "state_changed"},
|
||||||
));
|
));
|
||||||
Future.wait(futures).then((_) {
|
Future.wait(futures).then((_) {
|
||||||
_createUI();
|
if (isMobileAppEnabled) {
|
||||||
_fetchCompleter.complete();
|
_createUI();
|
||||||
|
_fetchCompleter.complete();
|
||||||
|
} else {
|
||||||
|
_fetchCompleter.completeError(HAError("Mobile app component not found", actions: [HAErrorAction.tryAgain(), HAErrorAction(type: HAErrorActionType.URL ,title: "Help",url: "http://ha-client.homemade.systems/docs#mobile-app")]));
|
||||||
|
}
|
||||||
}).catchError((e) {
|
}).catchError((e) {
|
||||||
_fetchCompleter.completeError(e);
|
_fetchCompleter.completeError(e);
|
||||||
});
|
});
|
||||||
@ -75,7 +79,7 @@ class HomeAssistant {
|
|||||||
await Connection().sendSocketMessage(type: "get_config").then((data) {
|
await Connection().sendSocketMessage(type: "get_config").then((data) {
|
||||||
_instanceConfig = Map.from(data);
|
_instanceConfig = Map.from(data);
|
||||||
}).catchError((e) {
|
}).catchError((e) {
|
||||||
throw {"errorCode": 1, "errorMessage": "Error getting config: $e"};
|
throw HAError("Error getting config: ${e}");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,13 +87,13 @@ class HomeAssistant {
|
|||||||
await Connection().sendSocketMessage(type: "get_states").then(
|
await Connection().sendSocketMessage(type: "get_states").then(
|
||||||
(data) => entities.parse(data)
|
(data) => entities.parse(data)
|
||||||
).catchError((e) {
|
).catchError((e) {
|
||||||
throw {"errorCode": 1, "errorMessage": "Error getting states: $e"};
|
throw HAError("Error getting states: $e");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _getLovelace() async {
|
Future _getLovelace() async {
|
||||||
await Connection().sendSocketMessage(type: "lovelace/config").then((data) => _rawLovelaceData = data).catchError((e) {
|
await Connection().sendSocketMessage(type: "lovelace/config").then((data) => _rawLovelaceData = data).catchError((e) {
|
||||||
throw {"errorCode": 1, "errorMessage": "Error getting lovelace config: $e"};
|
throw HAError("Error getting lovelace config: $e");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,7 +126,7 @@ class HomeAssistant {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
}).catchError((e) {
|
}).catchError((e) {
|
||||||
throw {"errorCode": 1, "errorMessage": "Error getting panels list: $e"};
|
throw HAError("Error getting panels list: $e");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
162
lib/main.dart
162
lib/main.dart
@ -277,7 +277,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
|||||||
|
|
||||||
if (_showErrorSubscription == null) {
|
if (_showErrorSubscription == null) {
|
||||||
_showErrorSubscription = eventBus.on<ShowErrorEvent>().listen((event){
|
_showErrorSubscription = eventBus.on<ShowErrorEvent>().listen((event){
|
||||||
_showErrorBottomBar(message: event.text, errorCode: event.errorCode);
|
_showErrorBottomBar(event.error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,17 +326,13 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_setErrorState(e) {
|
_setErrorState(HAError e) {
|
||||||
if (e["errorCode"] == null) {
|
if (e == null) {
|
||||||
_showErrorBottomBar(
|
_showErrorBottomBar(
|
||||||
message: "Unknown error",
|
HAError("Unknown error")
|
||||||
errorCode: 13
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
_showErrorBottomBar(
|
_showErrorBottomBar(e);
|
||||||
message: e != null ? e["errorMessage"] ?? "$e" : "Unknown error",
|
|
||||||
errorCode: e["errorCode"] != null ? e["errorCode"] : 99
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -538,108 +534,70 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _showErrorBottomBar({Key key, @required String message, @required int errorCode}) {
|
void _showErrorBottomBar(HAError error) {
|
||||||
TextStyle textStyle = TextStyle(
|
TextStyle textStyle = TextStyle(
|
||||||
color: Colors.blue,
|
color: Colors.blue,
|
||||||
fontSize: Sizes.nameFontSize
|
fontSize: Sizes.nameFontSize
|
||||||
);
|
);
|
||||||
_bottomBarColor = Colors.red.shade100;
|
_bottomBarColor = Colors.red.shade100;
|
||||||
switch (errorCode) {
|
List<Widget> actions = [];
|
||||||
case 9:
|
error.actions.forEach((HAErrorAction action) {
|
||||||
case 11:
|
switch (action.type) {
|
||||||
case 7:
|
case HAErrorActionType.FULL_RELOAD: {
|
||||||
case 1: {
|
actions.add(FlatButton(
|
||||||
_bottomBarAction = FlatButton(
|
child: Text("${action.title}", style: textStyle),
|
||||||
child: Text("Retry", style: textStyle),
|
onPressed: () {
|
||||||
onPressed: () {
|
_fullLoad();
|
||||||
//_scaffoldKey?.currentState?.hideCurrentSnackBar();
|
},
|
||||||
_quickLoad();
|
));
|
||||||
},
|
break;
|
||||||
);
|
}
|
||||||
break;
|
|
||||||
}
|
case HAErrorActionType.QUICK_RELOAD: {
|
||||||
|
actions.add(FlatButton(
|
||||||
case 5: {
|
child: Text("${action.title}", style: textStyle),
|
||||||
message = "Check connection settings";
|
onPressed: () {
|
||||||
_bottomBarAction = FlatButton(
|
_quickLoad();
|
||||||
child: Text("Open", style: textStyle),
|
},
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case HAErrorActionType.URL: {
|
||||||
|
actions.add(FlatButton(
|
||||||
|
child: Text("${action.title}", style: textStyle),
|
||||||
|
onPressed: () {
|
||||||
|
HAUtils.launchURLInCustomTab(context, "${action.url}");
|
||||||
|
},
|
||||||
|
));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case HAErrorActionType.OPEN_CONNECTION_SETTINGS: {
|
||||||
|
actions.add(FlatButton(
|
||||||
|
child: Text("${action.title}", style: textStyle),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
//_scaffoldKey?.currentState?.hideCurrentSnackBar();
|
|
||||||
Navigator.pushNamed(context, '/connection-settings');
|
Navigator.pushNamed(context, '/connection-settings');
|
||||||
},
|
},
|
||||||
);
|
));
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 60: {
|
|
||||||
_bottomBarAction = FlatButton(
|
|
||||||
child: Text("Login", style: textStyle),
|
|
||||||
onPressed: () {
|
|
||||||
_fullLoad();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 63:
|
|
||||||
case 61: {
|
|
||||||
_bottomBarAction = FlatButton(
|
|
||||||
child: Text("Try again", style: textStyle),
|
|
||||||
onPressed: () {
|
|
||||||
_fullLoad();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 62: {
|
|
||||||
_bottomBarAction = FlatButton(
|
|
||||||
child: Text("Login again", style: textStyle),
|
|
||||||
onPressed: () {
|
|
||||||
_fullLoad();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 10: {
|
|
||||||
_bottomBarAction = FlatButton(
|
|
||||||
child: Text("Reload", style: textStyle),
|
|
||||||
onPressed: () {
|
|
||||||
//_scaffoldKey?.currentState?.hideCurrentSnackBar();
|
|
||||||
_fullLoad();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 82:
|
|
||||||
case 81:
|
|
||||||
case 8: {
|
|
||||||
_bottomBarAction = FlatButton(
|
|
||||||
child: Text("Reconnect", style: textStyle),
|
|
||||||
onPressed: () {
|
|
||||||
_fullLoad();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
_bottomBarAction = FlatButton(
|
|
||||||
child: Text("Try again", style: textStyle),
|
|
||||||
onPressed: () {
|
|
||||||
_fullLoad();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setState(() {
|
});
|
||||||
_bottomBarProgress = false;
|
if (actions.isNotEmpty) {
|
||||||
_bottomBarText = "$message";
|
_bottomBarAction = Row(
|
||||||
_showBottomBar = true;
|
mainAxisSize: MainAxisSize.min,
|
||||||
});
|
children: actions,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.end,
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
_bottomBarAction = Container(height: 0.0, width: 0.0,);
|
||||||
|
}
|
||||||
|
setState(() {
|
||||||
|
_bottomBarProgress = false;
|
||||||
|
_bottomBarText = "${error.message}";
|
||||||
|
_showBottomBar = true;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
|
||||||
|
@ -45,6 +45,50 @@ class Logger {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class HAError {
|
||||||
|
String message;
|
||||||
|
final List<HAErrorAction> actions;
|
||||||
|
|
||||||
|
HAError(this.message, {this.actions: const [HAErrorAction.tryAgain()]});
|
||||||
|
|
||||||
|
HAError.unableToConnect({this.actions = const [HAErrorAction.tryAgain()]}) {
|
||||||
|
this.message = "Unable to connect to Home Assistant";
|
||||||
|
}
|
||||||
|
|
||||||
|
HAError.disconnected({this.actions = const [HAErrorAction.reconnect()]}) {
|
||||||
|
this.message = "Disconnected";
|
||||||
|
}
|
||||||
|
|
||||||
|
HAError.checkConnectionSettings({this.actions = const [HAErrorAction.reload(), HAErrorAction(title: "Settings", type: HAErrorActionType.OPEN_CONNECTION_SETTINGS)]}) {
|
||||||
|
this.message = "Check connection settings";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class HAErrorAction {
|
||||||
|
final String title;
|
||||||
|
final int type;
|
||||||
|
final String url;
|
||||||
|
|
||||||
|
const HAErrorAction({@required this.title, this.type: HAErrorActionType.FULL_RELOAD, this.url});
|
||||||
|
|
||||||
|
const HAErrorAction.tryAgain({this.title = "Try again", this.type = HAErrorActionType.FULL_RELOAD, this.url});
|
||||||
|
|
||||||
|
const HAErrorAction.reconnect({this.title = "Reconnect", this.type = HAErrorActionType.FULL_RELOAD, this.url});
|
||||||
|
|
||||||
|
const HAErrorAction.reload({this.title = "Reload", this.type = HAErrorActionType.FULL_RELOAD, this.url});
|
||||||
|
|
||||||
|
const HAErrorAction.loginAgain({this.title = "Login again", this.type = HAErrorActionType.FULL_RELOAD, this.url});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class HAErrorActionType {
|
||||||
|
static const FULL_RELOAD = 0;
|
||||||
|
static const QUICK_RELOAD = 1;
|
||||||
|
static const LOGOUT = 2;
|
||||||
|
static const URL = 3;
|
||||||
|
static const OPEN_CONNECTION_SETTINGS = 4;
|
||||||
|
}
|
||||||
|
|
||||||
class HAUtils {
|
class HAUtils {
|
||||||
static void launchURL(String url) async {
|
static void launchURL(String url) async {
|
||||||
if (await urlLauncher.canLaunch(url)) {
|
if (await urlLauncher.canLaunch(url)) {
|
||||||
@ -136,8 +180,7 @@ class ShowEntityPageEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ShowErrorEvent {
|
class ShowErrorEvent {
|
||||||
String text;
|
final HAError error;
|
||||||
int errorCode;
|
|
||||||
|
|
||||||
ShowErrorEvent(this.text, this.errorCode);
|
ShowErrorEvent(this.error);
|
||||||
}
|
}
|
Reference in New Issue
Block a user