From e5cde4700f41fd4fd9d5ceeb09f235afd034201e Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Wed, 28 Aug 2019 15:38:03 +0100 Subject: [PATCH] notificationDaemon: Catch exceptions while loading notifications An Endless OS system was found in the wild with a malformed .local/share/gnome-shell/notifications which causes _loadNotifications() to raise an exception. This exception was not previously handled and bubbles all the way out to gnome_shell_plugin_start(), whereupon the shell exit(1)s. The user could no longer log into their computer. Handle exceptions from _loadNotifications(), log them, and attempt to continue. Ensure that this._isLoading is set to 'false' even on error, so that future calls to _saveNotifications() can overwrite the (corrupt) state file. https://gitlab.gnome.org/GNOME/gnome-shell/issues/1552 --- js/ui/notificationDaemon.js | 42 ++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/js/ui/notificationDaemon.js b/js/ui/notificationDaemon.js index 3b8cf3350..580174c65 100644 --- a/js/ui/notificationDaemon.js +++ b/js/ui/notificationDaemon.js @@ -750,29 +750,33 @@ var GtkNotificationDaemon = class GtkNotificationDaemon { _loadNotifications() { this._isLoading = true; - let value = global.get_persistent_state('a(sa(sv))', 'notifications'); - if (value) { - let sources = value.deep_unpack(); - sources.forEach(([appId, notifications]) => { - if (notifications.length == 0) - return; - - let source; - try { - source = this._ensureAppSource(appId); - } catch (e) { - if (e instanceof InvalidAppError) + try { + let value = global.get_persistent_state('a(sa(sv))', 'notifications'); + if (value) { + let sources = value.deep_unpack(); + sources.forEach(([appId, notifications]) => { + if (notifications.length == 0) return; - throw e; - } - notifications.forEach(([notificationId, notification]) => { - source.addNotification(notificationId, notification.deep_unpack(), false); + let source; + try { + source = this._ensureAppSource(appId); + } catch (e) { + if (e instanceof InvalidAppError) + return; + throw e; + } + + notifications.forEach(([notificationId, notification]) => { + source.addNotification(notificationId, notification.deep_unpack(), false); + }); }); - }); + } + } catch (e) { + logError(e, 'Failed to load saved notifications'); + } finally { + this._isLoading = false; } - - this._isLoading = false; } _saveNotifications() {