[polari/wip/bastianilso/error-handling] let application.js handle the errors
- From: Bastian Ilsø Hougaard <bastianilso src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [polari/wip/bastianilso/error-handling] let application.js handle the errors
- Date: Fri, 24 Jul 2015 08:45:16 +0000 (UTC)
commit 4555914f0a548454218f728d54d33abade91c406
Author: Bastian Ilsø <bastianilso src gnome org>
Date: Wed Jul 22 09:04:48 2015 +0200
let application.js handle the errors
src/appNotifications.js | 219 +++++++++++++++++++++++++---------------------
src/application.js | 45 ++++++----
src/connections.js | 2 +-
src/mainWindow.js | 10 +--
4 files changed, 153 insertions(+), 123 deletions(-)
---
diff --git a/src/appNotifications.js b/src/appNotifications.js
index d0f1e0a..2b4007f 100644
--- a/src/appNotifications.js
+++ b/src/appNotifications.js
@@ -12,25 +12,24 @@ const AppNotification = new Lang.Class({
Abstract: true,
_init: function() {
- this.widget = new Gtk.Revealer({ reveal_child: true });
+ this.widget = new Gtk.Revealer({ reveal_child: false });
this.widget.transition_type = Gtk.RevealerTransitionType.SLIDE_DOWN;
-
- this.widget.connect('notify::child-revealed',
- Lang.bind(this, this._onChildRevealed));
},
close: function() {
this.widget.reveal_child = false;
+ this.widget.destroy();
+ this.widget = null;
+ },
+
+ open: function() {
+ this.widget.reveal_child = true;
},
+
get statusReason() {
return this._statusReason;
},
-
- _onChildRevealed: function() {
- if (!this.widget.child_revealed)
- this.widget.destroy();
- }
});
const CommandOutputNotification = new Lang.Class({
@@ -94,116 +93,126 @@ const GridOutput = new Lang.Class({
}
});
-const ConnectingNotification = new Lang.Class({
- Name: 'ConnectingNotification',
+const ErrorNotification = new Lang.Class({
+ Name: 'ErrorNotification',
Extends: AppNotification,
- _init: function(account) {
- //log('created a connecting notification..');
+ _init: function(account, window, error) {
this.parent();
- this._account = account;
+ //log('creating error notification..');
this._grid = new Gtk.Grid({ orientation: Gtk.Orientation.HORIZONTAL,
column_spacing: 12 });
- this._grid.add(new Gtk.Spinner({ active: true }));
-
- let text = _("Connecting to %s").format(account.display_name);
- let label = new Gtk.Label({ label: text });
- this._grid.add(label);
-
+ this._grid.add(new Gtk.Image({icon_name: 'dialog-error-symbolic' }));
+ this._account = account;
+ this._window = window;
+ this._button = new Gtk.Button({ valign: Gtk.Align.CENTER });
+ this._label = new Gtk.Label({ max_width_chars: 30, wrap: true });
+ this._populateNotification(error);
+ this._grid.add(this._label);
+ this._grid.add(this._button);
this.widget.add(this._grid);
this.widget.show_all();
-
let id = account.connect('notify::connection-status',
Lang.bind(this, this._onConnectionStatusChanged));
this.widget.connect('destroy',
function() {
account.disconnect(id);
});
- this._statusReason = Tp.ConnectionStatus.CONNECTING;
+ this._statusReason = error;
},
- _onConnectionStatusChanged: function(account) {
- if (account.connection_status == Tp.ConnectionStatus.CONNECTING)
- return;
- this.close();
- },
+ _populateNotification: function(error) {
+ // Not sure if it is necessary to support all types of error messages.
+ // Telepathy-idle only emit a small subset of all of them..
- close: function() {
- this.parent();
- this._account.notification = null;
+ if (error == Tp.error_get_dbus_name(Tp.Error.NETWORK_ERROR)) {
+ this._label.label = _("Unable to connect to %s").format(this._account.display_name);
+ let details = _("Polari disconnected due to a network error. Please check if the address field
is correct.");
+ this._button.label = "Edit Account";
+ this._button.connect('clicked', Lang.bind(this, this._editAccountAction, details));
+ } else if (error == Tp.error_get_dbus_name(Tp.Error.AUTHENTICATION_FAILED)) {
+ this._label.label = _("Authentication failed for %s").format(this._account.display_name);
+ this._button.label = "Retry";
+ this._button.connect('clicked', Lang.bind(this, this._retryAccountAction));
+ } else if (error == Tp.error_get_dbus_name(Tp.Error.CHANNEL_BANNED)) {
+ this._label.label = _("You are banned from this room.");
+ this._button.label = "Retry";
+ this._button.connect('clicked', Lang.bind(this, this._retryRoomAction));
+ } else if (error == Tp.error_get_dbus_name(Tp.Error.CHANNEL_FULL)) {
+ this._label.label = _("The room is full.");
+ this._button.label = "Retry";
+ this._button.connect('clicked', Lang.bind(this, this._retryRoomAction));
+ } else if (error == Tp.error_get_dbus_name(Tp.Error.CHANNEL_INVITE_ONLY)) {
+ this._label.label = _("The room is invite-only.");
+ this._button.label = "Retry";
+ this._button.connect('clicked', Lang.bind(this, this._retryRoomAction));
+ } else {
+ log('no match for: ' + error);
+ this._label.label = _("Polari failed to connect for an unknown reason.");
+ this._button.label = "Retry";
+ this._button.connect('clicked', Lang.bind(this, this._retryAccountAction));
+ }
},
-});
-
-const ErrorNotification = new Lang.Class({
- Name: 'ErrorNotification',
- Extends: AppNotification,
-
- _init: function(account, window, statusReason) {
- this.parent();
- this._account = account;
- this._grid = new Gtk.Grid({ orientation: Gtk.Orientation.HORIZONTAL,
- column_spacing: 12 });
-
- this._grid.add(new Gtk.Image({icon_name: 'dialog-error-symbolic' }));
- // Not sure if it is necessary to support all types of error messages.
- // Telepathy-idle only emit a small subset of all of them..
- this._connectionErrorMessages = {};
- this._connectionErrorMessages[Tp.error_get_dbus_name(Tp.Error.NETWORK_ERROR)]
- = _("Polari disconnected due to a network error. Please check if the address field is correct.");
- this._connectionErrorMessages[Tp.error_get_dbus_name(Tp.Error.AUTHENTICATION_FAILED)]
- = _("Authentication failed");
-
- let button = new Gtk.Button({label: "Edit Account",
- valign: Gtk.Align.CENTER });
- button.connect('clicked', Lang.bind(this, function() {
- log('clicked');
- let error = {message: this._getMessage(account.connection_error),
- icon_name: 'dialog-error-symbolic', widget: 'serverEntry'};
- account.error = error;
- let dialog = new Connections.ConnectionDetailsDialog(account);
- dialog.widget.transient_for = window;
- dialog.widget.show();
- dialog.widget.connect('response', Lang.bind(this,
- function(w, response) {
- dialog.widget.destroy();
- if (response == Gtk.ResponseType.OK)
- this.close();
- // should try to connect again but
- // we already try again when account info is updated in SSL patch
- }));
+ _editAccountAction: function(button, details) {
+ //log('clicked');
+ let error = {message: details,
+ icon_name: 'dialog-error-symbolic', widget: 'serverEntry'};
+ this._account.error = error;
+ let dialog = new Connections.ConnectionDetailsDialog(this._account);
+ dialog.widget.transient_for = this._window;
+ dialog.widget.show();
+ dialog.widget.connect('response', Lang.bind(this,
+ function(w, response) {
+ dialog.widget.destroy();
+ if (response == Gtk.ResponseType.OK)
+ this.close();
+ // should try to connect again but
+ // we already try again when account info is updated in SSL patch
}));
- log('creating Connecting Notification..');
- let text = _("Unable to connect to %s").format(account.display_name);
- let label = new Gtk.Label({ label: text, max_width_chars: 30, wrap: true });
- this._grid.add(label);
- this._grid.add(button);
- this.widget.add(this._grid);
- this.widget.show_all();
- let id = account.connect('notify::connection-status',
- Lang.bind(this, this._onConnectionStatusChanged));
- this.widget.connect('destroy',
- function() {
- account.disconnect(id);
- });
- this._statusReason = statusReason;
},
- _getMessage: function(connectionError) {
- let message;
- if (connectionError in this._connectionErrorMessages) {
- message = this._connectionErrorMessages[connectionError];
- } else {
- message = _("Unknown reason");
- }
- return message;
+ _retryRoomAction: function() {
+ /*log('clicked');
+ let error = {message: this._getMessage(account.connection_error),
+ icon_name: 'dialog-error-symbolic', widget: 'serverEntry'};
+ account.error = error;
+ let dialog = new Connections.ConnectionDetailsDialog(account);
+ dialog.widget.transient_for = window;
+ dialog.widget.show();
+ dialog.widget.connect('response', Lang.bind(this,
+ function(w, response) {
+ dialog.widget.destroy();
+ if (response == Gtk.ResponseType.OK)
+ this.close();
+ // should try to connect again but
+ // we already try again when account info is updated in SSL patch
+ }));*/
+ },
+
+ _retryAccountAction: function() {
+ /*log('clicked');
+ let error = {message: this._getMessage(account.connection_error),
+ icon_name: 'dialog-error-symbolic', widget: 'serverEntry'};
+ account.error = error;
+ let dialog = new Connections.ConnectionDetailsDialog(account);
+ dialog.widget.transient_for = window;
+ dialog.widget.show();
+ dialog.widget.connect('response', Lang.bind(this,
+ function(w, response) {
+ dialog.widget.destroy();
+ if (response == Gtk.ResponseType.OK)
+
+ // should try to connect again but
+ // we already try again when account info is updated in SSL patch
+ }));*/
},
_onConnectionStatusChanged: function(account) {
if (account.connection_status == Tp.ConnectionStatus.DISCONNECTED)
return;
- this.close();
+ //this.close();
},
});
@@ -231,15 +240,17 @@ const NotificationQueue = new Lang.Class({
this._notifications[params.identifier] = params;
//log('checking if ' + params.identifier + ' is active..');
//log('this._activeNotifications[' + params.type + '].identifier: ' +
this._activeNotifications[params.type].identifier)
- if (this._activeNotifications[params.type].identifier == params.identifier) {
- //log('..true. calling displayNotification.');
- this._displayNotification(params);
- }
+ if (this._activeNotifications[params.type].identifier != params.identifier)
+ return;
+ if (this._activeNotifications[params.type].notification == params.notification)
+ return;
+ //log('..true. calling displayNotification.');
+ this._displayNotification(params);
},
loadNotifications: function(identifier, type) {
- log('currently notifications are loaded for: ' + this._activeNotifications[type].identifier);
- log('the notification is: ' + this._activeNotifications[type].notification);
+ //log('current notice is ' + this._activeNotifications[type].notification
+ // + ' and is loaded for: ' + this._activeNotifications[type].identifier);
// We only perform this check if activeNotification has already been initialized.
// Otherwise we'll never be able to load notifications from this._activeNotifications.
if (this._activeNotifications[type]) {
@@ -261,13 +272,20 @@ const NotificationQueue = new Lang.Class({
},
_displayNotification: function(params) {
- log('now displaying ' + params.notification + ' for: ' + params.identifier);
+ //log('now displaying ' + params.notification + ' for: ' + params.identifier);
//log('_displayNotification: checking if any notifications of that type is visible..');
if (this._activeNotifications[params.type].notification) {
//log('_displayNotification: true. removing visible notification');
//this._activeNotifications[params.type].notification.close();
- this._grid.remove(this._activeNotifications[params.type].notification.widget);
+ //log('grid children: ' + this._grid.get_children().length);
+ if (this._activeNotifications[params.type].notification.widget) {
+ //log('removing ' + this._activeNotifications[params.type].notification);
+ if (!params.notification)
+ this._activeNotifications[params.type].notification.close();
+ else
+ this._grid.remove(this._activeNotifications[params.type].notification.widget);
+ }
}
//log('storing parameters inside this._activeNotifications[' + params.type + ']..');
this._activeNotifications[params.type] = params;
@@ -279,6 +297,7 @@ const NotificationQueue = new Lang.Class({
}
this._grid.add(params.notification.widget);
+ params.notification.open();
params.notification.widget.connect('destroy',
Lang.bind(this, this._updateVisibility));
this.widget.show();
diff --git a/src/application.js b/src/application.js
index 7262bfd..d7634dc 100644
--- a/src/application.js
+++ b/src/application.js
@@ -284,22 +284,14 @@ const Application = new Lang.Class({
this._onEnsureChannel, requestData));
},
- _retryRequest: function(requestData) {
- let account = requestData.account;
-
- // Try again with a different nick
- let params = account.dup_parameters_vardict().deep_unpack();
- let oldNick = params['account'].deep_unpack();
- let nick = oldNick + '_';
- this._updateAccountName(account, nick, Lang.bind(this,
- function() {
- this._ensureChannel(requestData);
- }));
- },
-
_onEnsureChannel: function(req, res, requestData) {
let account = req.account;
-
+ let roomError = { notification: null,
+ type: 'room',
+ identifier: requestData.roomId };
+ let accountError = { notification: null,
+ type: 'account',
+ identifier: account.get_path_suffix() };
try {
req.ensure_channel_finish(res);
@@ -307,18 +299,39 @@ const Application = new Lang.Class({
this._addSavedChannel(account, requestData.targetId);
} catch (e if e.matches(Tp.Error, Tp.Error.DISCONNECTED)) {
let error = account.connection_error;
+
if (error == ConnectionError.ALREADY_CONNECTED &&
requestData.retry++ < MAX_RETRIES) {
- this._retryRequest(requestData);
+ let params = account.dup_parameters_vardict().deep_unpack();
+ let oldNick = params['account'].deep_unpack();
+ let nick = oldNick + '_';
+ this._updateAccountName(account, nick, Lang.bind(this,
+ function() {
+ this._ensureChannel(requestData);
+ }));
return;
}
- if (error && error != ConnectionError.CANCELLED)
+ if (error && error != ConnectionError.CANCELLED) {
logError(e);
+ let notification =
+ new AppNotifications.ErrorNotification(account, this._window.window, error);
+ notification.widget.connect('destroy',
+ Lang.bind(this, function() {
+ this._ensureChannel(requestData);
+ }));
+ accountError.notification = notification;
+ }
} catch (e if e.matches(Tp.Error, Tp.Error.CANCELLED)) {
// interrupted by user request, don't log
} catch (e) {
logError(e, 'Failed to ensure channel');
+ let error = Tp.error_get_dbus_name(e.code);
+ roomError.notification =
+ new AppNotifications.ErrorNotification(account, this._window.window, error);
+ } finally {
+ this.notificationQueue.setNotification(roomError);
+ this.notificationQueue.setNotification(accountError);
}
if (requestData.retry > 0)
diff --git a/src/connections.js b/src/connections.js
index 4c9505c..e8cef0d 100644
--- a/src/connections.js
+++ b/src/connections.js
@@ -353,7 +353,7 @@ const ConnectionDetailsDialog = new Lang.Class({
this._confirmButton, 'sensitive',
GObject.BindingFlags.SYNC_CREATE);
this.widget.get_content_area().add(this._details);
- if (account.error)
+ if (account && account.error)
this.widget.get_content_area().add(this._createErrorMessage(account.error));
},
diff --git a/src/mainWindow.js b/src/mainWindow.js
index 2e6f86b..7de7347 100644
--- a/src/mainWindow.js
+++ b/src/mainWindow.js
@@ -55,10 +55,10 @@ const MainWindow = new Lang.Class({
);
this._accountsMonitor = AccountsMonitor.getDefault();
- this._accountsMonitor.connect('account-status-changed',
+ /*this._accountsMonitor.connect('account-status-changed',
Lang.bind(this, this._onAccountChanged));
this._accountsMonitor.connect('account-added',
- Lang.bind(this, this._onAccountChanged));
+ Lang.bind(this, this._onAccountChanged));*/
this._roomManager = ChatroomManager.getDefault();
this._roomManager.connect('active-changed',
@@ -120,7 +120,7 @@ const MainWindow = new Lang.Class({
},
_onAccountChanged: function(am, account) {
- log('***********');
+ //log('***********');
if (!account.connection_status_reason)
return;
let notification = null;
@@ -130,6 +130,7 @@ const MainWindow = new Lang.Class({
//log(account.display_name + ': we are connecting to the server..');
notification = new AppNotifications.ConnectingNotification(account);
} else if (account.connection_status == Tp.ConnectionStatus.DISCONNECTED) {
+ return;
if (statusReason == Tp.ConnectionStatusReason.REQUESTED)
return;
notification = new AppNotifications.ErrorNotification(account,
@@ -157,8 +158,6 @@ const MainWindow = new Lang.Class({
log(account.display_name + ': notification set to ' + notification + ' for ' +
account.get_path_suffix());
account.notification = notification;
- if (!notification)
- return;
},
_updateDecorations: function() {
@@ -208,7 +207,6 @@ const MainWindow = new Lang.Class({
log('**********')
log('loading archived notifications for: ' + room.account.get_path_suffix());
app.notificationQueue.loadNotifications(room.account.get_path_suffix(), 'account');
- log('**********')
//log('loading archived notifications for: ' + room.id);
app.notificationQueue.loadNotifications(room.id, 'room');
},
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]