diff --git a/services/sync/modules/notifications.js b/services/sync/modules/notifications.js index a3f59422887..0fe0a264240 100644 --- a/services/sync/modules/notifications.js +++ b/services/sync/modules/notifications.js @@ -125,9 +125,20 @@ Notification.prototype.buttons = []; * A button to display in a notification. */ function NotificationButton(label, accessKey, callback) { + function callbackWrapper() { + try { + callback.apply(this, arguments); + } catch (e) { + let logger = Log4Moz.Service.getLogger("Notifications"); + logger.error("An exception occurred: " + Utils.exceptionStr(e)); + logger.info(Utils.stackTrace(e)); + throw e; + } + } + this.label = label; this.accessKey = accessKey; - this.callback = callback; + this.callback = callbackWrapper; } function TabsNotification() { diff --git a/services/sync/tests/unit/test_notifications.js b/services/sync/tests/unit/test_notifications.js new file mode 100644 index 00000000000..3c27ded4729 --- /dev/null +++ b/services/sync/tests/unit/test_notifications.js @@ -0,0 +1,32 @@ +Cu.import("resource://weave/notifications.js"); + +function run_test() { + var logStats = initTestLogging("Info"); + + var blah = 0; + + function callback(i) { + blah = i; + } + + let button = new NotificationButton("label", "accessKey", callback); + + button.callback(5); + + do_check_eq(blah, 5); + do_check_eq(logStats.errorsLogged, 0); + + function badCallback() { + throw new Error("oops"); + } + + button = new NotificationButton("label", "accessKey", badCallback); + + try { + button.callback(); + } catch (e) { + do_check_eq(e.message, "oops"); + } + + do_check_eq(logStats.errorsLogged, 1); +}