diff --git a/src/object.js b/src/object.js index 03571f42a7..e958cd8657 100644 --- a/src/object.js +++ b/src/object.js @@ -15,6 +15,8 @@ var object = function () { return new object(); } + var util = require('./util'); + var m_this = this, m_eventHandlers = {}, m_idleHandlers = [], @@ -75,6 +77,10 @@ var object = function () { }); return m_this; } + if (!util.isFunction(handler)) { + console.warn('Handler for ' + event + ' is not a function', handler, m_this); + return m_this; + } if (!m_eventHandlers.hasOwnProperty(event)) { m_eventHandlers[event] = []; } @@ -107,7 +113,11 @@ var object = function () { if (m_eventHandlers.hasOwnProperty(event)) { m_eventHandlers[event].forEach(function (handler) { - handler.call(m_this, args); + try { + handler.call(m_this, args); + } catch (err) { + console.warn('Event handler for ' + event + ' threw an error', err); + } }); } diff --git a/tests/cases/object.js b/tests/cases/object.js index 2e7719b231..5fab1980a6 100644 --- a/tests/cases/object.js +++ b/tests/cases/object.js @@ -199,6 +199,33 @@ describe('geo.object', function () { expect(foo.ncalls).toBe(3); }); + it('Test a non-function handler', function () { + sinon.stub(console, 'warn', function () {}); + var obj = new geo.object(), + evtData = {}, + handler = new CallCounter(evtData); + + obj.geoOn('event1', undefined); + expect(console.warn.calledOnce); + obj.geoOn('event1', handler.call); + obj.geoTrigger('event1', evtData); + expect(handler.ncalls).toBe(1); + console.warn.restore(); + }); + + it('Test a handler that has an error', function () { + sinon.stub(console, 'warn', function () {}); + var obj = new geo.object(), + evtData = {}, + handler = new CallCounter(evtData); + + obj.geoOn('event1', function () { throw new Error('fail'); }); + obj.geoOn('event1', handler.call); + obj.geoTrigger('event1', evtData); + expect(handler.ncalls).toBe(1); + expect(console.warn.calledOnce); + console.warn.restore(); + }); }); });