History

Improve JS error tracking

Thibaut Courouble committed 9 years ago

Commit ae298601 parent 7e5c3fc3 files · +120 −73Browse files

Unified · Split

3 files
  1. assets/javascripts/app/app.coffee +1 −1
  2. assets/javascripts/app/db.coffee +2 −1
  3. assets/javascripts/vendor/raven.js +117 −71
assets/javascripts/app/app.coffee+1−1
@@ -58,7 +58,7 @@ · 57 unmodified lines
5858 tags:
5959 mode: if @isSingleDoc() then 'single' else 'full'
6060 iframe: (window.top isnt window).toString()
61− electron: window.process?.versions?.electron
61+ electron: (!!window.process?.versions?.electron).toString()
6262 shouldSendCallback: =>
6363 try
6464 if @isInjectionError()
assets/javascripts/app/db.coffee+2−1
@@ -60,7 +60,8 @@ class app.DB · 59 unmodified lines
6060 @error or= error
6161 console.error? 'IDB error', error if error
6262 @runCallbacks()
63− Raven.captureException error, level: 'warning' if error and reason == 'cant_open'
63+ if error and reason is 'cant_open'
64+ Raven.captureMessage "#{error.name}: #{error.message}", level: 'warning', fingerprint: [error.name]
6465 return
6566
6667 onQuotaExceededError: ->
assets/javascripts/vendor/raven.js+117−71
@@ -1,4 +1,4 @@
1−/*! Raven.js 3.11.0 (cb87941) | github.com/getsentry/raven-js */
1+/*! Raven.js 3.13.1 (f55d281) | github.com/getsentry/raven-js */
22
33 /*
44 * Includes TraceKit
@@ -11,35 +11,6 @@ · 6 unmodified lines
1111 */
1212
1313 (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Raven = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
14−exports = module.exports = stringify
15−exports.getSerialize = serializer
16−
17−function stringify(obj, replacer, spaces, cycleReplacer) {
18− return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces)
19−}
20−
21−function serializer(replacer, cycleReplacer) {
22− var stack = [], keys = []
23−
24− if (cycleReplacer == null) cycleReplacer = function(key, value) {
25− if (stack[0] === value) return "[Circular ~]"
26− return "[Circular ~." + keys.slice(0, stack.indexOf(value)).join(".") + "]"
27− }
28−
29− return function(key, value) {
30− if (stack.length > 0) {
31− var thisPos = stack.indexOf(this)
32− ~thisPos ? stack.splice(thisPos + 1) : stack.push(this)
33− ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key)
34− if (~stack.indexOf(value)) value = cycleReplacer.call(this, key, value)
35− }
36− else stack.push(value)
37−
38− return replacer == null ? value : replacer.call(this, key, value)
39− }
40−}
41−
42−},{}],2:[function(_dereq_,module,exports){
4314 'use strict';
4415
4516 function RavenConfigError(message) {
@@ -51,7 +22,7 @@ RavenConfigError.prototype.constructor = RavenConfigError; · 5 unmodified lines
5122
5223 module.exports = RavenConfigError;
5324
54−},{}],3:[function(_dereq_,module,exports){
25+},{}],2:[function(_dereq_,module,exports){
5526 'use strict';
5627
5728 var wrapMethod = function(console, level, callback) {
@@ -90,16 +61,20 @@ module.exports = { · 32 unmodified lines
9061 wrapMethod: wrapMethod
9162 };
9263
93−},{}],4:[function(_dereq_,module,exports){
64+},{}],3:[function(_dereq_,module,exports){
9465 (function (global){
9566 /*global XDomainRequest:false, __DEV__:false*/
9667 'use strict';
9768
9869 var TraceKit = _dereq_(6);
99−var RavenConfigError = _dereq_(2);
100−var stringify = _dereq_(1);
70+var stringify = _dereq_(7);
71+var RavenConfigError = _dereq_(1);
72+var utils = _dereq_(5);
73+
74+var isError = utils.isError,
75+ isObject = utils.isObject;
10176
102−var wrapConsoleMethod = _dereq_(3).wrapMethod;
77+var wrapConsoleMethod = _dereq_(2).wrapMethod;
10378
10479 var dsnKeys = 'source protocol user pass host port path'.split(' '),
10580 dsnPattern = /^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w\.-]+)(?::(\d+))?(\/.*)/;
@@ -141,7 +116,8 @@ function Raven() { · 35 unmodified lines
141116 collectWindowErrors: true,
142117 maxMessageLength: 0,
143118 stackTraceLimit: 50,
144− autoBreadcrumbs: true
119+ autoBreadcrumbs: true,
120+ sampleRate: 1
145121 };
146122 this._ignoreOnError = 0;
147123 this._isRavenInstalled = false;
@@ -176,7 +152,7 @@ Raven.prototype = { · 28 unmodified lines
176152 // webpack (using a build step causes webpack #1617). Grunt verifies that
177153 // this value matches package.json during build.
178154 // See: https://github.com/getsentry/raven-js/issues/465
179− VERSION: '3.11.0',
155+ VERSION: '3.13.1',
180156
181157 debug: false,
182158
@@ -1578,7 +1554,13 @@ Raven.prototype = { · 1395 unmodified lines
15781554 return;
15791555 }
15801556
1581− this._sendProcessedPayload(data);
1557+ if (typeof globalOptions.sampleRate === 'number') {
1558+ if (Math.random() < globalOptions.sampleRate) {
1559+ this._sendProcessedPayload(data);
1560+ }
1561+ } else {
1562+ this._sendProcessedPayload(data);
1563+ }
15821564 },
15831565
15841566 _getUuid: function () {
@@ -1674,24 +1656,18 @@ Raven.prototype = { · 89 unmodified lines
16741656 if (!hasCORS) return;
16751657
16761658 var url = opts.url;
1677− function handler() {
1678− if (request.status === 200) {
1679− if (opts.onSuccess) {
1680− opts.onSuccess();
1681− }
1682− } else if (opts.onError) {
1683− var err = new Error('Sentry error code: ' + request.status);
1684− err.request = request;
1685− opts.onError(err);
1686− }
1687− }
16881659
16891660 if ('withCredentials' in request) {
16901661 request.onreadystatechange = function () {
16911662 if (request.readyState !== 4) {
16921663 return;
1664+ } else if (request.status === 200) {
1665+ opts.onSuccess && opts.onSuccess();
1666+ } else if (opts.onError) {
1667+ var err = new Error('Sentry error code: ' + request.status);
1668+ err.request = request;
1669+ opts.onError(err);
16931670 }
1694− handler();
16951671 };
16961672 } else {
16971673 request = new XDomainRequest();
@@ -1700,7 +1676,16 @@ Raven.prototype = { · 2 unmodified lines
17001676 url = url.replace(/^https?:/, '');
17011677
17021678 // onreadystatechange not supported by XDomainRequest
1703− request.onload = handler;
1679+ if (opts.onSuccess) {
1680+ request.onload = opts.onSuccess;
1681+ }
1682+ if (opts.onError) {
1683+ request.onerror = function () {
1684+ var err = new Error('Sentry error code: XDomainRequest');
1685+ err.request = request;
1686+ opts.onError(err);
1687+ }
1688+ }
17041689 }
17051690
17061691 // NOTE: auth is intentionally sent as part of query string (NOT as custom
@@ -1749,25 +1734,12 @@ function isString(what) { · 42 unmodified lines
17491734 return objectPrototype.toString.call(what) === '[object String]';
17501735 }
17511736
1752−function isObject(what) {
1753− return typeof what === 'object' && what !== null;
1754−}
17551737
17561738 function isEmptyObject(what) {
17571739 for (var _ in what) return false; // eslint-disable-line guard-for-in, no-unused-vars
17581740 return true;
17591741 }
17601742
1761−// Sorta yanked from https://github.com/joyent/node/blob/aa3b4b4/lib/util.js#L560
1762−// with some tiny modifications
1763−function isError(what) {
1764− var toString = objectPrototype.toString.call(what);
1765− return isObject(what) &&
1766− toString === '[object Error]' ||
1767− toString === '[object Exception]' || // Firefox NS_ERROR_FAILURE Exceptions
1768− what instanceof Error;
1769−}
1770−
17711743 function each(obj, callback) {
17721744 var i, j;
17731745
@@ -2067,7 +2039,7 @@ Raven.prototype.setReleaseContext = Raven.prototype.setRelease; · 293 unmodified lines
20672039 module.exports = Raven;
20682040
20692041 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2070−},{"1":1,"2":2,"3":3,"6":6}],5:[function(_dereq_,module,exports){
2042+},{"1":1,"2":2,"5":5,"6":6,"7":7}],4:[function(_dereq_,module,exports){
20712043 (function (global){
20722044 /**
20732045 * Enforces a single instance of the Raven client, and the
@@ -2077,7 +2049,7 @@ module.exports = Raven; · 3 unmodified lines
20772049
20782050 'use strict';
20792051
2080−var RavenConstructor = _dereq_(4);
2052+var RavenConstructor = _dereq_(3);
20812053
20822054 // This is to be defensive in environments where window does not exist (see https://github.com/getsentry/raven-js/pull/785)
20832055 var _window = typeof window !== 'undefined' ? window
@@ -2104,10 +2076,33 @@ Raven.afterLoad(); · 20 unmodified lines
21042076 module.exports = Raven;
21052077
21062078 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2107−},{"4":4}],6:[function(_dereq_,module,exports){
2079+},{"3":3}],5:[function(_dereq_,module,exports){
2080+'use strict';
2081+
2082+function isObject(what) {
2083+ return typeof what === 'object' && what !== null;
2084+}
2085+
2086+// Sorta yanked from https://github.com/joyent/node/blob/aa3b4b4/lib/util.js#L560
2087+// with some tiny modifications
2088+function isError(what) {
2089+ var toString = {}.toString.call(what);
2090+ return isObject(what) &&
2091+ toString === '[object Error]' ||
2092+ toString === '[object Exception]' || // Firefox NS_ERROR_FAILURE Exceptions
2093+ what instanceof Error;
2094+}
2095+
2096+module.exports = {
2097+ isObject: isObject,
2098+ isError: isError
2099+};
2100+},{}],6:[function(_dereq_,module,exports){
21082101 (function (global){
21092102 'use strict';
21102103
2104+var utils = _dereq_(5);
2105+
21112106 /*
21122107 TraceKit - Cross brower stack traces
21132108
@@ -2134,7 +2129,7 @@ var _slice = [].slice; · 20 unmodified lines
21342129 var UNKNOWN_FUNCTION = '?';
21352130
21362131 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#Error_types
2137−var ERROR_TYPES_RE = /^(?:Uncaught (?:exception: )?)?((?:Eval|Internal|Range|Reference|Syntax|Type|URI)Error): ?(.*)$/;
2132+var ERROR_TYPES_RE = /^(?:[Uu]ncaught (?:exception: )?)?(?:((?:Eval|Internal|Range|Reference|Syntax|Type|URI|)Error): )?(.*)$/;
21382133
21392134 function getLocationHref() {
21402135 if (typeof document === 'undefined' || typeof document.location === 'undefined')
@@ -2143,6 +2138,7 @@ function getLocationHref() { · 2 unmodified lines
21432138 return document.location.href;
21442139 }
21452140
2141+
21462142 /**
21472143 * TraceKit.report: cross-browser processing of unhandled exceptions
21482144 *
@@ -2260,7 +2256,9 @@ TraceKit.report = (function reportModuleWrapper() { · 111 unmodified lines
22602256 if (lastExceptionStack) {
22612257 TraceKit.computeStackTrace.augmentStackTraceWithInitialElement(lastExceptionStack, url, lineNo, message);
22622258 processLastException();
2263− } else if (ex) {
2259+ } else if (ex && utils.isError(ex)) {
2260+ // non-string `ex` arg; attempt to extract stack trace
2261+
22642262 // New chrome and blink send along a real error object
22652263 // Let's just report that like a normal error.
22662264 // See: https://mikewest.org/2013/08/debugging-runtime-errors-with-window-onerror
@@ -2703,7 +2701,6 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() { · 436 unmodified lines
27032701 throw e;
27042702 }
27052703 }
2706−
27072704 return {
27082705 'name': ex.name,
27092706 'message': ex.message,
@@ -2720,5 +2717,54 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() { · 10 unmodified lines
27202717 module.exports = TraceKit;
27212718
27222719 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2723−},{}]},{},[5])(5)
2720+},{"5":5}],7:[function(_dereq_,module,exports){
2721+'use strict';
2722+
2723+/*
2724+ json-stringify-safe
2725+ Like JSON.stringify, but doesn't throw on circular references.
2726+
2727+ Originally forked from https://github.com/isaacs/json-stringify-safe
2728+ version 5.0.1 on 3/8/2017 and modified for IE8 compatibility.
2729+ Tests for this are in test/vendor.
2730+
2731+ ISC license: https://github.com/isaacs/json-stringify-safe/blob/master/LICENSE
2732+*/
2733+
2734+exports = module.exports = stringify
2735+exports.getSerialize = serializer
2736+
2737+function indexOf(haystack, needle) {
2738+ for (var i = 0; i < haystack.length; ++i) {
2739+ if (haystack[i] === needle) return i;
2740+ }
2741+ return -1;
2742+}
2743+
2744+function stringify(obj, replacer, spaces, cycleReplacer) {
2745+ return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces)
2746+}
2747+
2748+function serializer(replacer, cycleReplacer) {
2749+ var stack = [], keys = []
2750+
2751+ if (cycleReplacer == null) cycleReplacer = function(key, value) {
2752+ if (stack[0] === value) return '[Circular ~]'
2753+ return '[Circular ~.' + keys.slice(0, indexOf(stack, value)).join('.') + ']'
2754+ }
2755+
2756+ return function(key, value) {
2757+ if (stack.length > 0) {
2758+ var thisPos = indexOf(stack, this);
2759+ ~thisPos ? stack.splice(thisPos + 1) : stack.push(this)
2760+ ~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key)
2761+ if (~indexOf(stack, value)) value = cycleReplacer.call(this, key, value)
2762+ }
2763+ else stack.push(value)
2764+
2765+ return replacer == null ? value : replacer.call(this, key, value)
2766+ }
2767+}
2768+
2769+},{}]},{},[4])(4)
27242770 });