summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/assets/javascripts/raven/raven_config.js53
-rw-r--r--spec/javascripts/raven/raven_config_spec.js62
2 files changed, 115 insertions, 0 deletions
diff --git a/app/assets/javascripts/raven/raven_config.js b/app/assets/javascripts/raven/raven_config.js
index 9c756a4130b..6c20cd9aabd 100644
--- a/app/assets/javascripts/raven/raven_config.js
+++ b/app/assets/javascripts/raven/raven_config.js
@@ -1,6 +1,52 @@
import Raven from 'raven-js';
+const IGNORE_ERRORS = [
+ // Random plugins/extensions
+ 'top.GLOBALS',
+ // See: http://blog.errorception.com/2012/03/tale-of-unfindable-js-error. html
+ 'originalCreateNotification',
+ 'canvas.contentDocument',
+ 'MyApp_RemoveAllHighlights',
+ 'http://tt.epicplay.com',
+ 'Can\'t find variable: ZiteReader',
+ 'jigsaw is not defined',
+ 'ComboSearch is not defined',
+ 'http://loading.retry.widdit.com/',
+ 'atomicFindClose',
+ // Facebook borked
+ 'fb_xd_fragment',
+ // ISP "optimizing" proxy - `Cache-Control: no-transform` seems to
+ // reduce this. (thanks @acdha)
+ // See http://stackoverflow.com/questions/4113268
+ 'bmi_SafeAddOnload',
+ 'EBCallBackMessageReceived',
+ // See http://toolbar.conduit.com/Developer/HtmlAndGadget/Methods/JSInjection.aspx
+ 'conduitPage',
+];
+
+const IGNORE_URLS = [
+ // Facebook flakiness
+ /graph\.facebook\.com/i,
+ // Facebook blocked
+ /connect\.facebook\.net\/en_US\/all\.js/i,
+ // Woopra flakiness
+ /eatdifferent\.com\.woopra-ns\.com/i,
+ /static\.woopra\.com\/js\/woopra\.js/i,
+ // Chrome extensions
+ /extensions\//i,
+ /^chrome:\/\//i,
+ // Other plugins
+ /127\.0\.0\.1:4001\/isrunning/i, // Cacaoweb
+ /webappstoolbarba\.texthelp\.com\//i,
+ /metrics\.itunes\.apple\.com\.edgesuite\.net\//i,
+];
+
+const SAMPLE_RATE = 95;
+
const RavenConfig = {
+ IGNORE_ERRORS,
+ IGNORE_URLS,
+ SAMPLE_RATE,
init(options = {}) {
this.options = options;
@@ -13,6 +59,9 @@ const RavenConfig = {
Raven.config(this.options.sentryDsn, {
whitelistUrls: this.options.whitelistUrls,
environment: this.options.isProduction ? 'production' : 'development',
+ ignoreErrors: this.IGNORE_ERRORS,
+ ignoreUrls: this.IGNORE_URLS,
+ shouldSendCallback: this.shouldSendSample,
}).install();
},
@@ -42,6 +91,10 @@ const RavenConfig = {
},
});
},
+
+ shouldSendSample() {
+ return Math.random() * 100 <= this.SAMPLE_RATE;
+ },
};
export default RavenConfig;
diff --git a/spec/javascripts/raven/raven_config_spec.js b/spec/javascripts/raven/raven_config_spec.js
index 55f3949c740..78251b4f61b 100644
--- a/spec/javascripts/raven/raven_config_spec.js
+++ b/spec/javascripts/raven/raven_config_spec.js
@@ -2,6 +2,28 @@ import Raven from 'raven-js';
import RavenConfig from '~/raven/raven_config';
describe('RavenConfig', () => {
+ describe('IGNORE_ERRORS', () => {
+ it('should be an array of strings', () => {
+ const areStrings = RavenConfig.IGNORE_ERRORS.every(error => typeof error === 'string');
+
+ expect(areStrings).toBe(true);
+ });
+ });
+
+ describe('IGNORE_URLS', () => {
+ it('should be an array of regexps', () => {
+ const areRegExps = RavenConfig.IGNORE_URLS.every(url => url instanceof RegExp);
+
+ expect(areRegExps).toBe(true);
+ });
+ });
+
+ describe('SAMPLE_RATE', () => {
+ it('should be a finite number', () => {
+ expect(typeof RavenConfig.SAMPLE_RATE).toEqual('number');
+ });
+ });
+
describe('init', () => {
let options;
@@ -76,6 +98,9 @@ describe('RavenConfig', () => {
expect(Raven.config).toHaveBeenCalledWith(options.sentryDsn, {
whitelistUrls: options.whitelistUrls,
environment: 'production',
+ ignoreErrors: Raven.IGNORE_ERRORS,
+ ignoreUrls: Raven.IGNORE_URLS,
+ shouldSendCallback: Raven.shouldSendSample,
});
});
@@ -93,6 +118,9 @@ describe('RavenConfig', () => {
expect(Raven.config).toHaveBeenCalledWith(options.sentryDsn, {
whitelistUrls: options.whitelistUrls,
environment: 'development',
+ ignoreErrors: Raven.IGNORE_ERRORS,
+ ignoreUrls: Raven.IGNORE_URLS,
+ shouldSendCallback: Raven.shouldSendSample,
});
});
});
@@ -213,4 +241,38 @@ describe('RavenConfig', () => {
});
});
});
+
+ describe('shouldSendSample', () => {
+ let randomNumber;
+
+ beforeEach(() => {
+ RavenConfig.SAMPLE_RATE = 50;
+
+ spyOn(Math, 'random').and.callFake(() => randomNumber);
+ });
+
+ it('should call Math.random', () => {
+ RavenConfig.shouldSendSample();
+
+ expect(Math.random).toHaveBeenCalled();
+ });
+
+ it('should return true if the sample rate is greater than the random number * 100', () => {
+ randomNumber = 0.1;
+
+ expect(RavenConfig.shouldSendSample()).toBe(true);
+ });
+
+ it('should return false if the sample rate is less than the random number * 100', () => {
+ randomNumber = 0.9;
+
+ expect(RavenConfig.shouldSendSample()).toBe(false);
+ });
+
+ it('should return true if the sample rate is equal to the random number * 100', () => {
+ randomNumber = 0.5;
+
+ expect(RavenConfig.shouldSendSample()).toBe(true);
+ });
+ });
});