From acdd9622d2ababa4a59ee1d0d04a816791f5d795 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Mon, 9 Nov 2015 16:51:39 -0800 Subject: [PATCH 1/2] [Topic] Add test case ...which specifies desired behavior for nasa/openmctweb#231. --- platform/core/test/services/TopicSpec.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/platform/core/test/services/TopicSpec.js b/platform/core/test/services/TopicSpec.js index b389b19579..e3732cc240 100644 --- a/platform/core/test/services/TopicSpec.js +++ b/platform/core/test/services/TopicSpec.js @@ -65,6 +65,21 @@ define( expect(mockCallback).toHaveBeenCalledWith(testMessage); }); + it("is robust against errors thrown by listeners", function () { + var mockBadCallback = jasmine.createSpy("bad-callback"), + t = topic(); + + mockBadCallback.andCallFake(function () { + throw new Error("I'm afraid I can't do that."); + }); + + t.listen(mockBadCallback); + t.listen(mockCallback); + + t.notify(testMessage); + expect(mockCallback).toHaveBeenCalledWith(testMessage); + }); + }); } ); From e3e44f74d662832dac90a8c3a00805a867eb3ae0 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Mon, 9 Nov 2015 16:55:22 -0800 Subject: [PATCH 2/2] [Topic] Catch errors from listeners --- platform/core/bundle.json | 3 ++- platform/core/src/services/Topic.js | 10 ++++++++-- platform/core/test/services/TopicSpec.js | 7 ++++++- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/platform/core/bundle.json b/platform/core/bundle.json index 330ac1c2b9..12cedd9a5a 100644 --- a/platform/core/bundle.json +++ b/platform/core/bundle.json @@ -207,7 +207,8 @@ }, { "key": "topic", - "implementation": "services/Topic.js" + "implementation": "services/Topic.js", + "depends": [ "$log" ] }, { "key": "contextualize", diff --git a/platform/core/src/services/Topic.js b/platform/core/src/services/Topic.js index ca38dfcde7..99f042cd43 100644 --- a/platform/core/src/services/Topic.js +++ b/platform/core/src/services/Topic.js @@ -26,6 +26,8 @@ define( function () { "use strict"; + var ERROR_PREFIX = "Error when notifying listener: "; + /** * The `topic` service provides a way to create both named, * shared listeners and anonymous, private listeners. @@ -46,7 +48,7 @@ define( * @returns {Function} * @memberof platform/core */ - function Topic() { + function Topic($log) { var topics = {}; function createTopic() { @@ -63,7 +65,11 @@ define( }, notify: function (message) { listeners.forEach(function (listener) { - listener(message); + try { + listener(message); + } catch (e) { + $log.error(ERROR_PREFIX + e.message); + } }); } }; diff --git a/platform/core/test/services/TopicSpec.js b/platform/core/test/services/TopicSpec.js index e3732cc240..22865a2571 100644 --- a/platform/core/test/services/TopicSpec.js +++ b/platform/core/test/services/TopicSpec.js @@ -28,13 +28,18 @@ define( describe("The 'topic' service", function () { var topic, + mockLog, testMessage, mockCallback; beforeEach(function () { testMessage = { someKey: "some value"}; + mockLog = jasmine.createSpyObj( + '$log', + [ 'error', 'warn', 'info', 'debug' ] + ); mockCallback = jasmine.createSpy('callback'); - topic = new Topic(); + topic = new Topic(mockLog); }); it("notifies listeners on a topic", function () {