History

Update Raven.js

Thibaut Courouble committed 10 years ago

Commit 5db1ca71 parent c2dcd3d1 file · +218 −166Browse files

Unified · Split

assets/javascripts/vendor/raven.js+218−166
@@ -1,4 +1,4 @@
1/*! Raven.js 3.0.4 (0784c3c) | github.com/getsentry/raven-js */1/*! Raven.js 3.5.1 (bef9fa7) | github.com/getsentry/raven-js */
2 2
3/*3/*
4 * Includes TraceKit4 * Includes TraceKit
@@ -11,6 +11,35 @@ · 6 unmodified lines
11 */11 */
12 12
13(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){13(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){
14exports = module.exports = stringify
15exports.getSerialize = serializer
16
17function stringify(obj, replacer, spaces, cycleReplacer) {
18 return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces)
19}
20
21function 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){
14'use strict';43'use strict';
15 44
16function RavenConfigError(message) {45function RavenConfigError(message) {
@@ -22,7 +51,7 @@ RavenConfigError.prototype.constructor = RavenConfigError; · 5 unmodified lines
22 51
23module.exports = RavenConfigError;52module.exports = RavenConfigError;
24 53
25},{}],2:[function(_dereq_,module,exports){54},{}],3:[function(_dereq_,module,exports){
26'use strict';55'use strict';
27 56
28var wrapMethod = function(console, level, callback) {57var wrapMethod = function(console, level, callback) {
@@ -61,13 +90,14 @@ module.exports = { · 32 unmodified lines
61 wrapMethod: wrapMethod90 wrapMethod: wrapMethod
62};91};
63 92
64},{}],3:[function(_dereq_,module,exports){93},{}],4:[function(_dereq_,module,exports){
65/*global XDomainRequest:false*/94/*global XDomainRequest:false*/
66'use strict';95'use strict';
67 96
68var TraceKit = _dereq_(6);97var TraceKit = _dereq_(7);
69var RavenConfigError = _dereq_(1);98var RavenConfigError = _dereq_(2);
70var utils = _dereq_(5);99var utils = _dereq_(6);
100var stringify = _dereq_(1);
71 101
72var isFunction = utils.isFunction;102var isFunction = utils.isFunction;
73var isUndefined = utils.isUndefined;103var isUndefined = utils.isUndefined;
@@ -83,8 +113,9 @@ var uuid4 = utils.uuid4; · 9 unmodified lines
83var htmlTreeAsString = utils.htmlTreeAsString;113var htmlTreeAsString = utils.htmlTreeAsString;
84var parseUrl = utils.parseUrl;114var parseUrl = utils.parseUrl;
85var isString = utils.isString;115var isString = utils.isString;
116var fill = utils.fill;
86 117
87var wrapConsoleMethod = _dereq_(2).wrapMethod;118var wrapConsoleMethod = _dereq_(3).wrapMethod;
88 119
89var dsnKeys = 'source protocol user pass host port path'.split(' '),120var dsnKeys = 'source protocol user pass host port path'.split(' '),
90 dsnPattern = /^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w\.-]+)(?::(\d+))?(\/.*)/;121 dsnPattern = /^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w\.-]+)(?::(\d+))?(\/.*)/;
@@ -93,6 +124,7 @@ function now() { · 2 unmodified lines
93 return +new Date();124 return +new Date();
94}125}
95 126
127
96// First, check for JSON support128// First, check for JSON support
97// If there is no JSON, we no-op the core features of Raven129// If there is no JSON, we no-op the core features of Raven
98// since JSON is required to encode the payload130// since JSON is required to encode the payload
@@ -115,7 +147,8 @@ function Raven() { · 16 unmodified lines
115 crossOrigin: 'anonymous',147 crossOrigin: 'anonymous',
116 collectWindowErrors: true,148 collectWindowErrors: true,
117 maxMessageLength: 0,149 maxMessageLength: 0,
118 stackTraceLimit: 50150 stackTraceLimit: 50,
151 autoBreadcrumbs: true
119 };152 };
120 this._ignoreOnError = 0;153 this._ignoreOnError = 0;
121 this._isRavenInstalled = false;154 this._isRavenInstalled = false;
@@ -128,7 +161,6 @@ function Raven() { · 6 unmodified lines
128 this._startTime = now();161 this._startTime = now();
129 this._wrappedBuiltIns = [];162 this._wrappedBuiltIns = [];
130 this._breadcrumbs = [];163 this._breadcrumbs = [];
131 this._breadcrumbLimit = 20;
132 this._lastCapturedEvent = null;164 this._lastCapturedEvent = null;
133 this._keypressTimeout;165 this._keypressTimeout;
134 this._location = window.location;166 this._location = window.location;
@@ -150,7 +182,7 @@ Raven.prototype = { · 15 unmodified lines
150 // webpack (using a build step causes webpack #1617). Grunt verifies that182 // webpack (using a build step causes webpack #1617). Grunt verifies that
151 // this value matches package.json during build.183 // this value matches package.json during build.
152 // See: https://github.com/getsentry/raven-js/issues/465184 // See: https://github.com/getsentry/raven-js/issues/465
153 VERSION: '3.0.4',185 VERSION: '3.5.1',
154 186
155 debug: false,187 debug: false,
156 188
@@ -200,6 +232,22 @@ Raven.prototype = { · 43 unmodified lines
200 this._globalOptions.ignoreUrls = this._globalOptions.ignoreUrls.length ? joinRegExp(this._globalOptions.ignoreUrls) : false;232 this._globalOptions.ignoreUrls = this._globalOptions.ignoreUrls.length ? joinRegExp(this._globalOptions.ignoreUrls) : false;
201 this._globalOptions.whitelistUrls = this._globalOptions.whitelistUrls.length ? joinRegExp(this._globalOptions.whitelistUrls) : false;233 this._globalOptions.whitelistUrls = this._globalOptions.whitelistUrls.length ? joinRegExp(this._globalOptions.whitelistUrls) : false;
202 this._globalOptions.includePaths = joinRegExp(this._globalOptions.includePaths);234 this._globalOptions.includePaths = joinRegExp(this._globalOptions.includePaths);
235 this._globalOptions.maxBreadcrumbs = Math.max(0, Math.min(this._globalOptions.maxBreadcrumbs || 100, 100)); // default and hard limit is 100
236
237 var autoBreadcrumbDefaults = {
238 xhr: true,
239 console: true,
240 dom: true,
241 location: true
242 };
243
244 var autoBreadcrumbs = this._globalOptions.autoBreadcrumbs;
245 if ({}.toString.call(autoBreadcrumbs) === '[object Object]') {
246 autoBreadcrumbs = objectMerge(autoBreadcrumbDefaults, autoBreadcrumbs);
247 } else if (autoBreadcrumbs !== false) {
248 autoBreadcrumbs = autoBreadcrumbDefaults;
249 }
250 this._globalOptions.autoBreadcrumbs = autoBreadcrumbs;
203 251
204 this._globalKey = uri.user;252 this._globalKey = uri.user;
205 this._globalSecret = uri.pass && uri.pass.substr(1);253 this._globalSecret = uri.pass && uri.pass.substr(1);
@@ -210,14 +258,6 @@ Raven.prototype = { · 4 unmodified lines
210 this._globalEndpoint = this._globalServer +258 this._globalEndpoint = this._globalServer +
211 '/' + path + 'api/' + this._globalProject + '/store/';259 '/' + path + 'api/' + this._globalProject + '/store/';
212 260
213 if (this._globalOptions.fetchContext) {
214 TraceKit.remoteFetching = true;
215 }
216
217 if (this._globalOptions.linesOfContext) {
218 TraceKit.linesOfContext = this._globalOptions.linesOfContext;
219 }
220
221 TraceKit.collectWindowErrors = !!this._globalOptions.collectWindowErrors;261 TraceKit.collectWindowErrors = !!this._globalOptions.collectWindowErrors;
222 262
223 // return for chaining263 // return for chaining
@@ -238,7 +278,9 @@ Raven.prototype = { · 14 unmodified lines
238 TraceKit.report.subscribe(function () {278 TraceKit.report.subscribe(function () {
239 self._handleOnErrorStackInfo.apply(self, arguments);279 self._handleOnErrorStackInfo.apply(self, arguments);
240 });280 });
241 this._wrapBuiltIns();281 this._instrumentTryCatch();
282 if (self._globalOptions.autoBreadcrumbs)
283 this._instrumentBreadcrumbs();
242 284
243 // Install all of the plugins285 // Install all of the plugins
244 this._drainPlugins();286 this._drainPlugins();
@@ -429,7 +471,7 @@ Raven.prototype = { · 184 unmodified lines
429 }, obj);471 }, obj);
430 472
431 this._breadcrumbs.push(crumb);473 this._breadcrumbs.push(crumb);
432 if (this._breadcrumbs.length > this._breadcrumbLimit) {474 if (this._breadcrumbs.length > this._globalOptions.maxBreadcrumbs) {
433 this._breadcrumbs.shift();475 this._breadcrumbs.shift();
434 }476 }
435 },477 },
@@ -500,7 +542,20 @@ Raven.prototype = { · 64 unmodified lines
500 */542 */
501 getContext: function() {543 getContext: function() {
502 // lol javascript544 // lol javascript
503 return JSON.parse(JSON.stringify(this._globalContext));545 return JSON.parse(stringify(this._globalContext));
546 },
547
548
549 /*
550 * Set environment of application
551 *
552 * @param {string} environment Typically something like 'production'.
553 * @return {Raven}
554 */
555 setEnvironment: function(environment) {
556 this._globalOptions.environment = environment;
557
558 return this;
504 },559 },
505 560
506 /*561 /*
@@ -523,7 +578,10 @@ Raven.prototype = { · 16 unmodified lines
523 * @return {Raven}578 * @return {Raven}
524 */579 */
525 setDataCallback: function(callback) {580 setDataCallback: function(callback) {
526 this._globalOptions.dataCallback = callback;581 var original = this._globalOptions.dataCallback;
582 this._globalOptions.dataCallback = isFunction(callback)
583 ? function (data) { return callback(data, original); }
584 : callback;
527 585
528 return this;586 return this;
529 },587 },
@@ -536,7 +594,10 @@ Raven.prototype = { · 6 unmodified lines
536 * @return {Raven}594 * @return {Raven}
537 */595 */
538 setShouldSendCallback: function(callback) {596 setShouldSendCallback: function(callback) {
539 this._globalOptions.shouldSendCallback = callback;597 var original = this._globalOptions.shouldSendCallback;
598 this._globalOptions.shouldSendCallback = isFunction(callback)
599 ? function (data) { return callback(data, original); }
600 : callback;
540 601
541 return this;602 return this;
542 },603 },
@@ -794,16 +855,10 @@ Raven.prototype = { · 251 unmodified lines
794 /**855 /**
795 * Install any queued plugins856 * Install any queued plugins
796 */857 */
797 _wrapBuiltIns: function() {858 _instrumentTryCatch: function() {
798 var self = this;859 var self = this;
799 860
800 function fill(obj, name, replacement, noUndo) {861 var wrappedBuiltIns = self._wrappedBuiltIns;
801 var orig = obj[name];
802 obj[name] = replacement(orig);
803 if (!noUndo) {
804 self._wrappedBuiltIns.push([obj, name, orig]);
805 }
806 }
807 862
808 function wrapTimeFn(orig) {863 function wrapTimeFn(orig) {
809 return function (fn, t) { // preserve arity864 return function (fn, t) { // preserve arity
@@ -829,6 +884,8 @@ Raven.prototype = { · 19 unmodified lines
829 };884 };
830 }885 }
831 886
887 var autoBreadcrumbs = this._globalOptions.autoBreadcrumbs;
888
832 function wrapEventTarget(global) {889 function wrapEventTarget(global) {
833 var proto = window[global] && window[global].prototype;890 var proto = window[global] && window[global].prototype;
834 if (proto && proto.hasOwnProperty && proto.hasOwnProperty('addEventListener')) {891 if (proto && proto.hasOwnProperty && proto.hasOwnProperty('addEventListener')) {
@@ -842,10 +899,10 @@ Raven.prototype = { · 7 unmodified lines
842 // can sometimes get 'Permission denied to access property "handle Event'899 // can sometimes get 'Permission denied to access property "handle Event'
843 }900 }
844 901
845 902 // More breadcrumb DOM capture ... done here and not in `_instrumentBreadcrumbs`
846 // TODO: more than just click903 // so that we don't have more than one wrapper function
847 var before;904 var before;
848 if (global === 'EventTarget' || global === 'Node') {905 if (autoBreadcrumbs && autoBreadcrumbs.dom && (global === 'EventTarget' || global === 'Node')) {
849 if (evtName === 'click'){906 if (evtName === 'click'){
850 before = self._breadcrumbEventHandler(evtName);907 before = self._breadcrumbEventHandler(evtName);
851 } else if (evtName === 'keypress') {908 } else if (evtName === 'keypress') {
@@ -854,39 +911,24 @@ Raven.prototype = { · 2 unmodified lines
854 }911 }
855 return orig.call(this, evtName, self.wrap(fn, undefined, before), capture, secure);912 return orig.call(this, evtName, self.wrap(fn, undefined, before), capture, secure);
856 };913 };
857 });914 }, wrappedBuiltIns);
858 fill(proto, 'removeEventListener', function (orig) {915 fill(proto, 'removeEventListener', function (orig) {
859 return function (evt, fn, capture, secure) {916 return function (evt, fn, capture, secure) {
860 fn = fn && (fn.__raven_wrapper__ ? fn.__raven_wrapper__ : fn);917 fn = fn && (fn.__raven_wrapper__ ? fn.__raven_wrapper__ : fn);
861 return orig.call(this, evt, fn, capture, secure);918 return orig.call(this, evt, fn, capture, secure);
862 };919 };
863 });920 }, wrappedBuiltIns);
864 }921 }
865 }922 }
866 923
867 function wrapProp(prop, xhr) {924 fill(window, 'setTimeout', wrapTimeFn, wrappedBuiltIns);
868 if (prop in xhr && isFunction(xhr[prop])) {925 fill(window, 'setInterval', wrapTimeFn, wrappedBuiltIns);
869 fill(xhr, prop, function (orig) {
870 return self.wrap(orig);
871 }, true /* noUndo */); // don't track filled methods on XHR instances
872 }
873 }
874
875 fill(window, 'setTimeout', wrapTimeFn);
876 fill(window, 'setInterval', wrapTimeFn);
877 if (window.requestAnimationFrame) {926 if (window.requestAnimationFrame) {
878 fill(window, 'requestAnimationFrame', function (orig) {927 fill(window, 'requestAnimationFrame', function (orig) {
879 return function (cb) {928 return function (cb) {
880 return orig(self.wrap(cb));929 return orig(self.wrap(cb));
881 };930 };
882 });931 }, wrappedBuiltIns);
883 }
884
885 // Capture breadcrubms from any click that is unhandled / bubbled up all the way
886 // to the document. Do this before we instrument addEventListener.
887 if (this._hasDocument) {
888 document.addEventListener('click', self._breadcrumbEventHandler('click'));
889 document.addEventListener('keypress', self._keypressEventHandler());
890 }932 }
891 933
892 // event targets borrowed from bugsnag-js:934 // event targets borrowed from bugsnag-js:
@@ -896,7 +938,41 @@ Raven.prototype = { · 3 unmodified lines
896 wrapEventTarget(eventTargets[i]);938 wrapEventTarget(eventTargets[i]);
897 }939 }
898 940
899 if ('XMLHttpRequest' in window) {941 var $ = window.jQuery || window.$;
942 if ($ && $.fn && $.fn.ready) {
943 fill($.fn, 'ready', function (orig) {
944 return function (fn) {
945 return orig.call(this, self.wrap(fn));
946 };
947 }, wrappedBuiltIns);
948 }
949 },
950
951
952 /**
953 * Instrument browser built-ins w/ breadcrumb capturing
954 * - XMLHttpRequests
955 * - DOM interactions (click/typing)
956 * - window.location changes
957 * - console
958 *
959 * Can be disabled or individually configured via the `autoBreadcrumbs` config option
960 */
961 _instrumentBreadcrumbs: function () {
962 var self = this;
963 var autoBreadcrumbs = this._globalOptions.autoBreadcrumbs;
964
965 var wrappedBuiltIns = self._wrappedBuiltIns;
966
967 function wrapProp(prop, xhr) {
968 if (prop in xhr && isFunction(xhr[prop])) {
969 fill(xhr, prop, function (orig) {
970 return self.wrap(orig);
971 }); // intentionally don't track filled methods on XHR instances
972 }
973 }
974
975 if (autoBreadcrumbs.xhr && 'XMLHttpRequest' in window) {
900 var xhrproto = XMLHttpRequest.prototype;976 var xhrproto = XMLHttpRequest.prototype;
901 fill(xhrproto, 'open', function(origOpen) {977 fill(xhrproto, 'open', function(origOpen) {
902 return function (method, url) { // preserve arity978 return function (method, url) { // preserve arity
@@ -912,7 +988,7 @@ Raven.prototype = { · 9 unmodified lines
912 988
913 return origOpen.apply(this, arguments);989 return origOpen.apply(this, arguments);
914 };990 };
915 });991 }, wrappedBuiltIns);
916 992
917 fill(xhrproto, 'send', function(origSend) {993 fill(xhrproto, 'send', function(origSend) {
918 return function (data) { // preserve arity994 return function (data) { // preserve arity
@@ -941,7 +1017,7 @@ Raven.prototype = { · 22 unmodified lines
941 if ('onreadystatechange' in xhr && isFunction(xhr.onreadystatechange)) {1017 if ('onreadystatechange' in xhr && isFunction(xhr.onreadystatechange)) {
942 fill(xhr, 'onreadystatechange', function (orig) {1018 fill(xhr, 'onreadystatechange', function (orig) {
943 return self.wrap(orig, undefined, onreadystatechangeHandler);1019 return self.wrap(orig, undefined, onreadystatechangeHandler);
944 }, true /* noUndo */);1020 } /* intentionally don't track this instrumentation */);
945 } else {1021 } else {
946 // if onreadystatechange wasn't actually set by the page on this xhr, we1022 // if onreadystatechange wasn't actually set by the page on this xhr, we
947 // are free to set our own and capture the breadcrumb1023 // are free to set our own and capture the breadcrumb
@@ -950,11 +1026,31 @@ Raven.prototype = { · 2 unmodified lines
950 1026
951 return origSend.apply(this, arguments);1027 return origSend.apply(this, arguments);
952 };1028 };
953 });1029 }, wrappedBuiltIns);
1030 }
1031
1032 // Capture breadcrumbs from any click that is unhandled / bubbled up all the way
1033 // to the document. Do this before we instrument addEventListener.
1034 if (autoBreadcrumbs.dom && this._hasDocument) {
1035 if (document.addEventListener) {
1036 document.addEventListener('click', self._breadcrumbEventHandler('click'), false);
1037 document.addEventListener('keypress', self._keypressEventHandler(), false);
1038 }
1039 else {
1040 // IE8 Compatibility
1041 document.attachEvent('onclick', self._breadcrumbEventHandler('click'));
1042 document.attachEvent('onkeypress', self._keypressEventHandler());
1043 }
954 }1044 }
955 1045
956 // record navigation (URL) changes1046 // record navigation (URL) changes
957 if ('history' in window && history.pushState) {1047 // NOTE: in Chrome App environment, touching history.pushState, *even inside
1048 // a try/catch block*, will cause Chrome to output an error to console.error
1049 // borrowed from: https://github.com/angular/angular.js/pull/13945/files
1050 var chrome = window.chrome;
1051 var isChromePackagedApp = chrome && chrome.app && chrome.app.runtime;
1052 var hasPushState = !isChromePackagedApp && window.history && history.pushState;
1053 if (autoBreadcrumbs.location && hasPushState) {
958 // TODO: remove onpopstate handler on uninstall()1054 // TODO: remove onpopstate handler on uninstall()
959 var oldOnPopState = window.onpopstate;1055 var oldOnPopState = window.onpopstate;
960 window.onpopstate = function () {1056 window.onpopstate = function () {
@@ -969,7 +1065,7 @@ Raven.prototype = { · 8 unmodified lines
969 fill(history, 'pushState', function (origPushState) {1065 fill(history, 'pushState', function (origPushState) {
970 // note history.pushState.length is 0; intentionally not declaring1066 // note history.pushState.length is 0; intentionally not declaring
971 // params to preserve 0 arity1067 // params to preserve 0 arity
972 return function(/* state, title, url */) {1068 return function (/* state, title, url */) {
973 var url = arguments.length > 2 ? arguments[2] : undefined;1069 var url = arguments.length > 2 ? arguments[2] : undefined;
974 1070
975 // url argument is optional1071 // url argument is optional
@@ -980,32 +1076,24 @@ Raven.prototype = { · 4 unmodified lines
980 1076
981 return origPushState.apply(this, arguments);1077 return origPushState.apply(this, arguments);
982 };1078 };
983 });1079 }, wrappedBuiltIns);
984 }1080 }
985 1081
986 // console1082 if (autoBreadcrumbs.console && 'console' in window && console.log) {
987 var consoleMethodCallback = function (msg, data) {1083 // console
988 self.captureBreadcrumb({1084 var consoleMethodCallback = function (msg, data) {
989 message: msg,1085 self.captureBreadcrumb({
990 level: data.level,1086 message: msg,
991 category: 'console'1087 level: data.level,
992 });1088 category: 'console'
993 };1089 });
1090 };
994 1091
995 if ('console' in window && console.log) {
996 each(['debug', 'info', 'warn', 'error', 'log'], function (_, level) {1092 each(['debug', 'info', 'warn', 'error', 'log'], function (_, level) {
997 wrapConsoleMethod(console, level, consoleMethodCallback);1093 wrapConsoleMethod(console, level, consoleMethodCallback);
998 });1094 });
999 }1095 }
1000 1096
1001 var $ = window.jQuery || window.$;
1002 if ($ && $.fn && $.fn.ready) {
1003 fill($.fn, 'ready', function (orig) {
1004 return function (fn) {
1005 return orig.call(this, self.wrap(fn));
1006 };
1007 });
1008 }
1009 },1097 },
1010 1098
1011 _restoreBuiltIns: function () {1099 _restoreBuiltIns: function () {
@@ -1106,13 +1194,7 @@ Raven.prototype = { · 94 unmodified lines
1106 lineno: frame.line,1194 lineno: frame.line,
1107 colno: frame.column,1195 colno: frame.column,
1108 'function': frame.func || '?'1196 'function': frame.func || '?'
1109 }, context = this._extractContextFromFrame(frame), i;1197 };
1110
1111 if (context) {
1112 var keys = ['pre_context', 'context_line', 'post_context'];
1113 i = 3;
1114 while (i--) normalized[keys[i]] = context[i];
1115 }
1116 1198
1117 normalized.in_app = !( // determine if an exception came from outside of our app1199 normalized.in_app = !( // determine if an exception came from outside of our app
1118 // first we check the global includePaths list.1200 // first we check the global includePaths list.
@@ -1126,55 +1208,12 @@ Raven.prototype = { · 7 unmodified lines
1126 return normalized;1208 return normalized;
1127 },1209 },
1128 1210
1129 _extractContextFromFrame: function(frame) {
1130 // immediately check if we should even attempt to parse a context
1131 if (!frame.context || !this._globalOptions.fetchContext) return;
1132
1133 var context = frame.context,
1134 pivot = ~~(context.length / 2),
1135 i = context.length, isMinified = false;
1136
1137 while (i--) {
1138 // We're making a guess to see if the source is minified or not.
1139 // To do that, we make the assumption if *any* of the lines passed
1140 // in are greater than 300 characters long, we bail.
1141 // Sentry will see that there isn't a context
1142 if (context[i].length > 300) {
1143 isMinified = true;
1144 break;
1145 }
1146 }
1147
1148 if (isMinified) {
1149 // The source is minified and we don't know which column. Fuck it.
1150 if (isUndefined(frame.column)) return;
1151
1152 // If the source is minified and has a frame column
1153 // we take a chunk of the offending line to hopefully shed some light
1154 return [
1155 [], // no pre_context
1156 context[pivot].substr(frame.column, 50), // grab 50 characters, starting at the offending column
1157 [] // no post_context
1158 ];
1159 }
1160
1161 return [
1162 context.slice(0, pivot), // pre_context
1163 context[pivot], // context_line
1164 context.slice(pivot + 1) // post_context
1165 ];
1166 },
1167
1168 _processException: function(type, message, fileurl, lineno, frames, options) {1211 _processException: function(type, message, fileurl, lineno, frames, options) {
1169 var stacktrace, fullMessage;1212 var stacktrace;
1170 1213
1171 if (!!this._globalOptions.ignoreErrors.test && this._globalOptions.ignoreErrors.test(message)) return;1214 if (!!this._globalOptions.ignoreErrors.test && this._globalOptions.ignoreErrors.test(message)) return;
1172 1215
1173 message += '';1216 message += '';
1174 message = truncate(message, this._globalOptions.maxMessageLength);
1175
1176 fullMessage = (type ? type + ': ' : '') + message;
1177 fullMessage = truncate(fullMessage, this._globalOptions.maxMessageLength);
1178 1217
1179 if (frames && frames.length) {1218 if (frames && frames.length) {
1180 fileurl = frames[0].filename || fileurl;1219 fileurl = frames[0].filename || fileurl;
@@ -1204,8 +1243,7 @@ Raven.prototype = { · 23 unmodified lines
1204 stacktrace: stacktrace1243 stacktrace: stacktrace
1205 }]1244 }]
1206 },1245 },
1207 culprit: fileurl,1246 culprit: fileurl
1208 message: fullMessage
1209 }, options);1247 }, options);
1210 1248
1211 // Fire away!1249 // Fire away!
@@ -1216,7 +1254,9 @@ Raven.prototype = { · 4 unmodified lines
1216 // For now, we only want to truncate the two different messages1254 // For now, we only want to truncate the two different messages
1217 // but this could/should be expanded to just trim everything1255 // but this could/should be expanded to just trim everything
1218 var max = this._globalOptions.maxMessageLength;1256 var max = this._globalOptions.maxMessageLength;
1219 data.message = truncate(data.message, max);1257 if (data.message) {
1258 data.message = truncate(data.message, max);
1259 }
1220 if (data.exception) {1260 if (data.exception) {
1221 var exception = data.exception.values[0];1261 var exception = data.exception.values[0];
1222 exception.value = truncate(exception.value, max);1262 exception.value = truncate(exception.value, max);
@@ -1247,8 +1287,6 @@ Raven.prototype = { · 24 unmodified lines
1247 1287
1248 1288
1249 _send: function(data) {1289 _send: function(data) {
1250 var self = this;
1251
1252 var globalOptions = this._globalOptions;1290 var globalOptions = this._globalOptions;
1253 1291
1254 var baseData = {1292 var baseData = {
@@ -1286,6 +1324,9 @@ Raven.prototype = { · 31 unmodified lines
1286 data.user = this._globalContext.user;1324 data.user = this._globalContext.user;
1287 }1325 }
1288 1326
1327 // Include the environment if it's defined in globalOptions
1328 if (globalOptions.environment) data.environment = globalOptions.environment;
1329
1289 // Include the release if it's defined in globalOptions1330 // Include the release if it's defined in globalOptions
1290 if (globalOptions.release) data.release = globalOptions.release;1331 if (globalOptions.release) data.release = globalOptions.release;
1291 1332
@@ -1306,6 +1347,13 @@ Raven.prototype = { · 14 unmodified lines
1306 return;1347 return;
1307 }1348 }
1308 1349
1350 this._sendProcessedPayload(data);
1351 },
1352
1353 _sendProcessedPayload: function(data, callback) {
1354 var self = this;
1355 var globalOptions = this._globalOptions;
1356
1309 // Send along an event_id if not explicitly passed.1357 // Send along an event_id if not explicitly passed.
1310 // This event_id can be used to reference the error within Sentry itself.1358 // This event_id can be used to reference the error within Sentry itself.
1311 // Set lastEventId after we know the error should actually be sent1359 // Set lastEventId after we know the error should actually be sent
@@ -1327,10 +1375,14 @@ Raven.prototype = { · 15 unmodified lines
1327 auth.sentry_secret = this._globalSecret;1375 auth.sentry_secret = this._globalSecret;
1328 }1376 }
1329 1377
1378 var exception = data.exception && data.exception.values[0];
1330 this.captureBreadcrumb({1379 this.captureBreadcrumb({
1331 category: 'sentry',1380 category: 'sentry',
1332 message: data.message,1381 message: exception
1333 event_id: data.event_id1382 ? (exception.type ? exception.type + ': ' : '') + exception.value
1383 : data.message,
1384 event_id: data.event_id,
1385 level: data.level || 'error' // presume error unless specified
1334 });1386 });
1335 1387
1336 var url = this._globalEndpoint;1388 var url = this._globalEndpoint;
@@ -1344,12 +1396,15 @@ Raven.prototype = { · 7 unmodified lines
1344 data: data,1396 data: data,
1345 src: url1397 src: url
1346 });1398 });
1399 callback && callback();
1347 },1400 },
1348 onError: function failure() {1401 onError: function failure(error) {
1349 self._triggerEvent('failure', {1402 self._triggerEvent('failure', {
1350 data: data,1403 data: data,
1351 src: url1404 src: url
1352 });1405 });
1406 error = error || new Error('Raven send failed (no additional details provided)');
1407 callback && callback(error);
1353 }1408 }
1354 });1409 });
1355 },1410 },
@@ -1371,7 +1426,7 @@ Raven.prototype = { · 15 unmodified lines
1371 opts.onSuccess();1426 opts.onSuccess();
1372 }1427 }
1373 } else if (opts.onError) {1428 } else if (opts.onError) {
1374 opts.onError();1429 opts.onError(new Error('Sentry error code: ' + request.status));
1375 }1430 }
1376 }1431 }
1377 1432
@@ -1395,14 +1450,7 @@ Raven.prototype = { · 17 unmodified lines
1395 // NOTE: auth is intentionally sent as part of query string (NOT as custom1450 // NOTE: auth is intentionally sent as part of query string (NOT as custom
1396 // HTTP header) so as to avoid preflight CORS requests1451 // HTTP header) so as to avoid preflight CORS requests
1397 request.open('POST', url + '?' + urlencode(opts.auth));1452 request.open('POST', url + '?' + urlencode(opts.auth));
1398 request.send(JSON.stringify(opts.data));1453 request.send(stringify(opts.data));
1399 },
1400
1401 // Note: this is shitty, but I can't figure out how to get
1402 // sinon to stub document.createElement without breaking everything
1403 // so this wrapper is just so I can stub it for tests.
1404 _newImage: function() {
1405 return document.createElement('img');
1406 },1454 },
1407 1455
1408 _logDebug: function(level) {1456 _logDebug: function(level) {
@@ -1431,7 +1479,7 @@ Raven.prototype.setReleaseContext = Raven.prototype.setRelease; · 22 unmodified lines
1431 1479
1432module.exports = Raven;1480module.exports = Raven;
1433 1481
1434},{"1":1,"2":2,"5":5,"6":6}],4:[function(_dereq_,module,exports){1482},{"1":1,"2":2,"3":3,"6":6,"7":7}],5:[function(_dereq_,module,exports){
1435/**1483/**
1436 * Enforces a single instance of the Raven client, and the1484 * Enforces a single instance of the Raven client, and the
1437 * main entry point for Raven. If you are a consumer of the1485 * main entry point for Raven. If you are a consumer of the
@@ -1440,7 +1488,7 @@ module.exports = Raven; · 2 unmodified lines
1440 1488
1441'use strict';1489'use strict';
1442 1490
1443var RavenConstructor = _dereq_(3);1491var RavenConstructor = _dereq_(4);
1444 1492
1445var _Raven = window.Raven;1493var _Raven = window.Raven;
1446 1494
@@ -1461,7 +1509,7 @@ Raven.afterLoad(); · 14 unmodified lines
1461 1509
1462module.exports = Raven;1510module.exports = Raven;
1463 1511
1464},{"3":3}],5:[function(_dereq_,module,exports){1512},{"4":4}],6:[function(_dereq_,module,exports){
1465/*eslint no-extra-parens:0*/1513/*eslint no-extra-parens:0*/
1466'use strict';1514'use strict';
1467 1515
@@ -1700,6 +1748,21 @@ function htmlElementAsString(elem) { · 232 unmodified lines
1700 return out.join('');1748 return out.join('');
1701}1749}
1702 1750
1751/**
1752 * Polyfill a method
1753 * @param obj object e.g. `document`
1754 * @param name method name present on object e.g. `addEventListener`
1755 * @param replacement replacement function
1756 * @param track {optional} record instrumentation to an array
1757 */
1758function fill(obj, name, replacement, track) {
1759 var orig = obj[name];
1760 obj[name] = replacement(orig);
1761 if (track) {
1762 track.push([obj, name, orig]);
1763 }
1764}
1765
1703module.exports = {1766module.exports = {
1704 isUndefined: isUndefined,1767 isUndefined: isUndefined,
1705 isFunction: isFunction,1768 isFunction: isFunction,
@@ -1716,13 +1779,14 @@ module.exports = { · 10 unmodified lines
1716 uuid4: uuid4,1779 uuid4: uuid4,
1717 htmlTreeAsString: htmlTreeAsString,1780 htmlTreeAsString: htmlTreeAsString,
1718 htmlElementAsString: htmlElementAsString,1781 htmlElementAsString: htmlElementAsString,
1719 parseUrl: parseUrl1782 parseUrl: parseUrl,
1783 fill: fill
1720};1784};
1721 1785
1722},{}],6:[function(_dereq_,module,exports){1786},{}],7:[function(_dereq_,module,exports){
1723'use strict';1787'use strict';
1724 1788
1725var utils = _dereq_(5);1789var utils = _dereq_(6);
1726 1790
1727var hasKey = utils.hasKey;1791var hasKey = utils.hasKey;
1728var isString = utils.isString;1792var isString = utils.isString;
@@ -1734,10 +1798,7 @@ var isUndefined = utils.isUndefined; · 5 unmodified lines
1734*/1798*/
1735 1799
1736var TraceKit = {1800var TraceKit = {
1737 remoteFetching: false,
1738 collectWindowErrors: true,1801 collectWindowErrors: true,
1739 // 3 lines before, the offending line, 3 lines after
1740 linesOfContext: 7,
1741 debug: false1802 debug: false
1742};1803};
1743 1804
@@ -1897,7 +1958,6 @@ TraceKit.report = (function reportModuleWrapper() { · 153 unmodified lines
1897 }1958 }
1898 1959
1899 location.func = UNKNOWN_FUNCTION;1960 location.func = UNKNOWN_FUNCTION;
1900 location.context = null;
1901 1961
1902 stack = {1962 stack = {
1903 'name': name,1963 'name': name,
@@ -2000,7 +2060,6 @@ TraceKit.report = (function reportModuleWrapper() { · 96 unmodified lines
2000 * s.stack[i].args - arguments passed to the function, if known2060 * s.stack[i].args - arguments passed to the function, if known
2001 * s.stack[i].line - line number, if known2061 * s.stack[i].line - line number, if known
2002 * s.stack[i].column - column number, if known2062 * s.stack[i].column - column number, if known
2003 * s.stack[i].context - an array of source code lines; the middle element corresponds to the correct line#
2004 *2063 *
2005 * Supports:2064 * Supports:
2006 * - Firefox: full stack trace with line numbers and unreliable column2065 * - Firefox: full stack trace with line numbers and unreliable column
@@ -2109,7 +2168,7 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() { · 102 unmodified lines
2109 2168
2110 var chrome = /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|<anonymous>).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i,2169 var chrome = /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|<anonymous>).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i,
2111 gecko = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|\[native).*?)(?::(\d+))?(?::(\d+))?\s*$/i,2170 gecko = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|\[native).*?)(?::(\d+))?(?::(\d+))?\s*$/i,
2112 winjs = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:ms-appx|https?|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i,2171 winjs = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i,
2113 lines = ex.stack.split('\n'),2172 lines = ex.stack.split('\n'),
2114 stack = [],2173 stack = [],
2115 parts,2174 parts,
@@ -2150,10 +2209,6 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() { · 34 unmodified lines
2150 element.func = UNKNOWN_FUNCTION;2209 element.func = UNKNOWN_FUNCTION;
2151 }2210 }
2152 2211
2153 if (element.line) {
2154 element.context = null;
2155 }
2156
2157 stack.push(element);2212 stack.push(element);
2158 }2213 }
2159 2214
@@ -2219,7 +2274,6 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() { · 59 unmodified lines
2219 if (!element.func && element.line) {2274 if (!element.func && element.line) {
2220 element.func = UNKNOWN_FUNCTION;2275 element.func = UNKNOWN_FUNCTION;
2221 }2276 }
2222 element.context = [lines[line + 1]];
2223 2277
2224 stack.push(element);2278 stack.push(element);
2225 }2279 }
@@ -2307,7 +2361,6 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() { · 81 unmodified lines
2307 if (!item.func) {2361 if (!item.func) {
2308 item.func = UNKNOWN_FUNCTION;2362 item.func = UNKNOWN_FUNCTION;
2309 }2363 }
2310 item.context = [lines[line + 1]];
2311 2364
2312 stack.push(item);2365 stack.push(item);
2313 }2366 }
@@ -2357,7 +2410,6 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() { · 43 unmodified lines
2357 return false; // already in stack trace2410 return false; // already in stack trace
2358 } else if (!stackInfo.stack[0].line && stackInfo.stack[0].func === initial.func) {2411 } else if (!stackInfo.stack[0].line && stackInfo.stack[0].func === initial.func) {
2359 stackInfo.stack[0].line = initial.line;2412 stackInfo.stack[0].line = initial.line;
2360 stackInfo.stack[0].context = initial.context;
2361 return false;2413 return false;
2362 }2414 }
2363 }2415 }
@@ -2512,5 +2564,5 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() { · 148 unmodified lines
2512 2564
2513module.exports = TraceKit;2565module.exports = TraceKit;
2514 2566
2515},{"5":5}]},{},[4])(4)2567},{"6":6}]},{},[5])(5)
2516});2568});