diff --git a/src/raven.js b/src/raven.js index 742b56bc02b0..3fe2896d4e57 100644 --- a/src/raven.js +++ b/src/raven.js @@ -101,6 +101,10 @@ var Raven = { TK.remoteFetching = true; } + if (globalOptions.collectWindowErrors) { + TK.collectWindowErrors = true; + } + if (globalOptions.linesOfContext) { TK.linesOfContext = globalOptions.linesOfContext; } @@ -120,7 +124,7 @@ var Raven = { install: function() { if (!isSetup()) return; - TK.report.subscribe(handleStackInfo); + TK.report.subscribe(handleErrorReport); return Raven; }, @@ -182,7 +186,7 @@ var Raven = { * @return {Raven} */ uninstall: function() { - TK.report.unsubscribe(handleStackInfo); + TK.report.unsubscribe(handleErrorReport); return Raven; }, @@ -338,6 +342,24 @@ function getAuthQueryString() { return cachedAuth; } +function handleErrorReport(stackInfo, options) { + var cb = globalOptions.shouldReportErrorCallback, + logged = false; + + if (cb && cb(stackInfo, options, handleStack)) { + handleStack(); + } else if(!cb) { + handleStack(); + } + + function handleStack() { + if (!logged) { + logged = true; + handleStackInfo(stackInfo, options); + } + } +} + function handleStackInfo(stackInfo, options) { var frames = []; diff --git a/test/raven.test.js b/test/raven.test.js index 7e2fe4b2c6e0..cbe5ef2903a5 100644 --- a/test/raven.test.js +++ b/test/raven.test.js @@ -765,6 +765,71 @@ describe('globals', function() { }); }); +describe('handleErrorReport', function() { + afterEach(function() { + flushRavenState(); + }); + + it('should pass call handleStackInfo', function() { + var stackInfo = {}, + options = {} + + setupRaven(); + this.sinon.stub(window, 'handleStackInfo') + + handleErrorReport() + assert.isTrue(window.handleStackInfo.calledOnce) + }) + + it('should not call handleStackInfo if cb returns false', function() { + var cb = this.sinon.stub().returns(false) + this.sinon.stub(window, 'handleStackInfo') + Raven.config(SENTRY_DSN, { + shouldReportErrorCallback: cb + }) + handleErrorReport() + assert.isTrue(cb.calledOnce) + assert.equal(window.handleStackInfo.callCount, 0) + }) + + it('should call handleStackInfo if cb returns true', function() { + var cb = this.sinon.stub().returns(true) + this.sinon.stub(window, 'handleStackInfo') + Raven.config(SENTRY_DSN, { + shouldReportErrorCallback: cb + }) + handleErrorReport() + assert.isTrue(cb.calledOnce) + assert.isTrue(window.handleStackInfo.calledOnce) + }) + + it('should allow cb call handleStackInfo through a callback', function() { + var cb = function(stackInfo, options, done) { + done() + } + this.sinon.stub(window, 'handleStackInfo') + Raven.config(SENTRY_DSN, { + shouldReportErrorCallback: cb + }) + handleErrorReport() + assert.isTrue(window.handleStackInfo.calledOnce) + }) + + it('handleStackInfo should only be calledOnce per error', function() { + var cb = function(stackInfo, options, done) { + done() + done() + return true + } + this.sinon.stub(window, 'handleStackInfo') + Raven.config(SENTRY_DSN, { + shouldReportErrorCallback: cb + }) + handleErrorReport() + assert.equal(window.handleStackInfo.callCount, 1) + }) +}) + describe('Raven (public API)', function() { afterEach(function() { flushRavenState(); @@ -868,7 +933,7 @@ describe('Raven (public API)', function() { this.sinon.stub(TK.report, 'subscribe'); assert.equal(Raven, Raven.install()); assert.isTrue(TK.report.subscribe.calledOnce); - assert.equal(TK.report.subscribe.lastCall.args[0], handleStackInfo); + assert.equal(TK.report.subscribe.lastCall.args[0], handleErrorReport); }); }); @@ -963,7 +1028,7 @@ describe('Raven (public API)', function() { this.sinon.stub(TK.report, 'unsubscribe'); Raven.uninstall(); assert.isTrue(TK.report.unsubscribe.calledOnce); - assert.equal(TK.report.unsubscribe.lastCall.args[0], handleStackInfo); + assert.equal(TK.report.unsubscribe.lastCall.args[0], handleErrorReport); }); });