Comparing version 1.1.3 to 1.1.11
{ | ||
"name": "raven-js", | ||
"version": "1.1.3", | ||
"version": "1.1.11", | ||
"dependencies": {}, | ||
"main": "dist/raven.js" | ||
} |
@@ -1,2 +0,2 @@ | ||
/*! Raven.js 1.1.3 (d81942a) | github.com/getsentry/raven-js */ | ||
/*! Raven.js 1.1.11 (11645a0) | github.com/getsentry/raven-js */ | ||
@@ -7,3 +7,3 @@ /* | ||
* | ||
* Copyright 2013 Matt Robenolt and other contributors | ||
* Copyright 2014 Matt Robenolt and other contributors | ||
* Released under the BSD license | ||
@@ -13,2 +13,5 @@ * https://github.com/getsentry/raven-js/blob/master/LICENSE | ||
*/ | ||
;(function(window, undefined){ | ||
'use strict'; | ||
/* | ||
@@ -19,8 +22,9 @@ TraceKit - Cross brower stack traces - github.com/occ/TraceKit | ||
;(function(window, undefined) { | ||
var TraceKit = { | ||
remoteFetching: false, | ||
collectWindowErrors: true, | ||
// 3 lines before, the offending line, 3 lines after | ||
linesOfContext: 7 | ||
}; | ||
var TraceKit = {}; | ||
var _oldTraceKit = window.TraceKit; | ||
// global reference to slice | ||
@@ -32,26 +36,2 @@ var _slice = [].slice; | ||
/** | ||
* _has, a better form of hasOwnProperty | ||
* Example: _has(MainHostObject, property) === true/false | ||
* | ||
* @param {Object} host object to check property | ||
* @param {string} key to check | ||
*/ | ||
function _has(object, key) { | ||
return Object.prototype.hasOwnProperty.call(object, key); | ||
} | ||
function _isUndefined(what) { | ||
return typeof what === 'undefined'; | ||
} | ||
/** | ||
* TraceKit.noConflict: Export TraceKit out to another variable | ||
* Example: var TK = TraceKit.noConflict() | ||
*/ | ||
TraceKit.noConflict = function noConflict() { | ||
window.TraceKit = _oldTraceKit; | ||
return TraceKit; | ||
}; | ||
/** | ||
* TraceKit.wrap: Wrap any function in a TraceKit reporter | ||
@@ -116,2 +96,3 @@ * Example: func = TraceKit.wrap(func); | ||
var handlers = [], | ||
lastArgs = null, | ||
lastException = null, | ||
@@ -142,12 +123,20 @@ lastExceptionStack = null; | ||
/** | ||
* Remove all crash handlers. | ||
*/ | ||
function unsubscribeAll() { | ||
uninstallGlobalHandler(); | ||
handlers = []; | ||
} | ||
/** | ||
* Dispatch stack information to all handlers. | ||
* @param {Object.<string, *>} stack | ||
*/ | ||
function notifyHandlers(stack, windowError) { | ||
function notifyHandlers(stack, isWindowError) { | ||
var exception = null; | ||
if (windowError && !TraceKit.collectWindowErrors) { | ||
if (isWindowError && !TraceKit.collectWindowErrors) { | ||
return; | ||
} | ||
for (var i in handlers) { | ||
if (_has(handlers, i)) { | ||
if (hasKey(handlers, i)) { | ||
try { | ||
@@ -175,4 +164,7 @@ handlers[i].apply(null, [stack].concat(_slice.call(arguments, 2))); | ||
* occurred. | ||
* @param {?(number|string)} colNo The column number at which the error | ||
* occurred. | ||
* @param {?Error} ex The actual Error object. | ||
*/ | ||
function traceKitWindowOnError(message, url, lineNo) { | ||
function traceKitWindowOnError(message, url, lineNo, colNo, ex) { | ||
var stack = null; | ||
@@ -182,9 +174,14 @@ | ||
TraceKit.computeStackTrace.augmentStackTraceWithInitialElement(lastExceptionStack, url, lineNo, message); | ||
stack = lastExceptionStack; | ||
lastExceptionStack = null; | ||
lastException = null; | ||
processLastException(); | ||
} else if (ex) { | ||
// New chrome and blink send along a real error object | ||
// Let's just report that like a normal error. | ||
// See: https://mikewest.org/2013/08/debugging-runtime-errors-with-window-onerror | ||
stack = TraceKit.computeStackTrace(ex); | ||
notifyHandlers(stack, true); | ||
} else { | ||
var location = { | ||
'url': url, | ||
'line': lineNo | ||
'line': lineNo, | ||
'column': colNo | ||
}; | ||
@@ -194,12 +191,9 @@ location.func = TraceKit.computeStackTrace.guessFunctionName(location.url, location.line); | ||
stack = { | ||
'mode': 'onerror', | ||
'message': message, | ||
'url': document.location.href, | ||
'stack': [location], | ||
'useragent': navigator.userAgent | ||
'stack': [location] | ||
}; | ||
notifyHandlers(stack, true); | ||
} | ||
notifyHandlers(stack, 'from window.onerror'); | ||
if (_oldOnerrorHandler) { | ||
@@ -214,3 +208,3 @@ return _oldOnerrorHandler.apply(this, arguments); | ||
{ | ||
if (_onErrorHandlerInstalled === true) { | ||
if (_onErrorHandlerInstalled) { | ||
return; | ||
@@ -223,7 +217,29 @@ } | ||
function uninstallGlobalHandler () | ||
{ | ||
if (!_onErrorHandlerInstalled) { | ||
return; | ||
} | ||
window.onerror = _oldOnerrorHandler; | ||
_onErrorHandlerInstalled = false; | ||
_oldOnerrorHandler = undefined; | ||
} | ||
function processLastException() { | ||
var _lastExceptionStack = lastExceptionStack, | ||
_lastArgs = lastArgs; | ||
lastArgs = null; | ||
lastExceptionStack = null; | ||
lastException = null; | ||
notifyHandlers.apply(null, [_lastExceptionStack, false].concat(_lastArgs)); | ||
} | ||
/** | ||
* Reports an unhandled Error to TraceKit. | ||
* @param {Error} ex | ||
* @param {?boolean} rethrow If false, do not re-throw the exception. | ||
* Only used for window.onerror to not cause an infinite loop of | ||
* rethrowing. | ||
*/ | ||
function report(ex) { | ||
function report(ex, rethrow) { | ||
var args = _slice.call(arguments, 1); | ||
@@ -234,6 +250,3 @@ if (lastExceptionStack) { | ||
} else { | ||
var s = lastExceptionStack; | ||
lastExceptionStack = null; | ||
lastException = null; | ||
notifyHandlers.apply(null, [s, null].concat(args)); | ||
processLastException(); | ||
} | ||
@@ -245,2 +258,3 @@ } | ||
lastException = ex; | ||
lastArgs = args; | ||
@@ -253,9 +267,9 @@ // If the stack trace is incomplete, wait for 2 seconds for | ||
if (lastException === ex) { | ||
lastExceptionStack = null; | ||
lastException = null; | ||
notifyHandlers.apply(null, [stack, null].concat(args)); | ||
processLastException(); | ||
} | ||
}, (stack.incomplete ? 2000 : 0)); | ||
throw ex; // re-throw to propagate to the top level (and cause window.onerror) | ||
if (rethrow !== false) { | ||
throw ex; // re-throw to propagate to the top level (and cause window.onerror) | ||
} | ||
} | ||
@@ -265,2 +279,3 @@ | ||
report.unsubscribe = unsubscribe; | ||
report.uninstall = unsubscribeAll; | ||
return report; | ||
@@ -284,3 +299,2 @@ }()); | ||
* s.stack[i].context - an array of source code lines; the middle element corresponds to the correct line# | ||
* s.mode - 'stack', 'stacktrace', 'multiline', 'callers', 'onerror', or 'failed' -- method used to collect the stack trace | ||
* | ||
@@ -352,3 +366,3 @@ * Supports: | ||
try { | ||
function getXHR() { | ||
var getXHR = function() { | ||
try { | ||
@@ -360,3 +374,3 @@ return new window.XMLHttpRequest(); | ||
} | ||
} | ||
}; | ||
@@ -378,3 +392,4 @@ var request = getXHR(); | ||
function getSource(url) { | ||
if (!_has(sourceCache, url)) { | ||
if (!isString(url)) return []; | ||
if (!hasKey(sourceCache, url)) { | ||
// URL needs to be able to fetched within the acceptable domain. Otherwise, | ||
@@ -417,3 +432,3 @@ // cross-domain errors will be triggered. | ||
if (!_isUndefined(line)) { | ||
if (!isUndefined(line)) { | ||
if ((m = reGuessFunction.exec(line))) { | ||
@@ -457,3 +472,3 @@ return m[1]; | ||
for (var i = start; i < end; ++i) { | ||
if (!_isUndefined(source[i])) { | ||
if (!isUndefined(source[i])) { | ||
context.push(source[i]); | ||
@@ -622,2 +637,3 @@ } | ||
// ex.lineNumber = 59 | ||
// ex.columnNumber = 69 | ||
// ex.stack = ...stack trace... (see the example below) | ||
@@ -654,4 +670,4 @@ // ex.name = ReferenceError | ||
var chrome = /^\s*at (?:((?:\[object object\])?\S+) )?\(?((?:file|http|https):.*?):(\d+)(?::(\d+))?\)?\s*$/i, | ||
gecko = /^\s*(\S*)(?:\((.*?)\))?@((?:file|http|https).*?):(\d+)(?::(\d+))?\s*$/i, | ||
var chrome = /^\s*at (?:((?:\[object object\])?\S+(?: \[as \S+\])?) )?\(?((?:file|https?):.*?):(\d+)(?::(\d+))?\)?\s*$/i, | ||
gecko = /^\s*(\S*)(?:\((.*?)\))?@((?:file|https?).*?):(\d+)(?::(\d+))?\s*$/i, | ||
lines = ex.stack.split('\n'), | ||
@@ -694,6 +710,2 @@ stack = [], | ||
if (stack[0] && stack[0].line && !stack[0].column && reference) { | ||
stack[0].column = findSourceInLine(reference[1], stack[0].url, stack[0].line); | ||
} | ||
if (!stack.length) { | ||
@@ -703,9 +715,16 @@ return null; | ||
if (stack[0].line && !stack[0].column && reference) { | ||
stack[0].column = findSourceInLine(reference[1], stack[0].url, stack[0].line); | ||
} else if (!stack[0].column && !isUndefined(ex.columnNumber)) { | ||
// FireFox uses this awesome columnNumber property for its top frame | ||
// Also note, Firefox's column number is 0-based and everything else expects 1-based, | ||
// so adding 1 | ||
stack[0].column = ex.columnNumber + 1; | ||
} | ||
return { | ||
'mode': 'stack', | ||
'name': ex.name, | ||
'message': ex.message, | ||
'url': document.location.href, | ||
'stack': stack, | ||
'useragent': navigator.userAgent | ||
'stack': stack | ||
}; | ||
@@ -763,8 +782,6 @@ } | ||
return { | ||
'mode': 'stacktrace', | ||
'name': ex.name, | ||
'message': ex.message, | ||
'url': document.location.href, | ||
'stack': stack, | ||
'useragent': navigator.userAgent | ||
'stack': stack | ||
}; | ||
@@ -802,4 +819,4 @@ } | ||
var lineRE1 = /^\s*Line (\d+) of linked script ((?:file|http|https)\S+)(?:: in function (\S+))?\s*$/i, | ||
lineRE2 = /^\s*Line (\d+) of inline#(\d+) script in ((?:file|http|https)\S+)(?:: in function (\S+))?\s*$/i, | ||
var lineRE1 = /^\s*Line (\d+) of linked script ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i, | ||
lineRE2 = /^\s*Line (\d+) of inline#(\d+) script in ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i, | ||
lineRE3 = /^\s*Line (\d+) of function script\s*$/i, | ||
@@ -815,3 +832,3 @@ stack = [], | ||
for (i in scripts) { | ||
if (_has(scripts, i) && !scripts[i].src) { | ||
if (hasKey(scripts, i) && !scripts[i].src) { | ||
inlineScriptBlocks.push(scripts[i]); | ||
@@ -878,8 +895,6 @@ } | ||
return { | ||
'mode': 'multiline', | ||
'name': ex.name, | ||
'message': lines[0], | ||
'url': document.location.href, | ||
'stack': stack, | ||
'useragent': navigator.userAgent | ||
'stack': stack | ||
}; | ||
@@ -1012,8 +1027,6 @@ } | ||
var result = { | ||
'mode': 'callers', | ||
'name': ex.name, | ||
'message': ex.message, | ||
'url': document.location.href, | ||
'stack': stack, | ||
'useragent': navigator.userAgent | ||
'stack': stack | ||
}; | ||
@@ -1080,5 +1093,3 @@ augmentStackTraceWithInitialElement(result, ex.sourceURL || ex.fileName, ex.line || ex.lineNumber, ex.message || ex.description); | ||
return { | ||
'mode': 'failed' | ||
}; | ||
return {}; | ||
} | ||
@@ -1098,4 +1109,2 @@ | ||
} | ||
return null; | ||
} | ||
@@ -1111,24 +1120,2 @@ | ||
//Default options: | ||
if (!TraceKit.remoteFetching) { | ||
TraceKit.remoteFetching = true; | ||
} | ||
if (!TraceKit.collectWindowErrors) { | ||
TraceKit.collectWindowErrors = true; | ||
} | ||
if (!TraceKit.linesOfContext || TraceKit.linesOfContext < 1) { | ||
// 3 lines before, the offending line, 3 lines after | ||
TraceKit.linesOfContext = 7; | ||
} | ||
// Export to global object | ||
window.TraceKit = TraceKit; | ||
}(window)); | ||
;(function(window, undefined){ | ||
'use strict'; | ||
@@ -1142,2 +1129,3 @@ | ||
lastCapturedException, | ||
lastEventId, | ||
globalServer, | ||
@@ -1158,7 +1146,2 @@ globalUser, | ||
var TK = TraceKit.noConflict(); | ||
// Disable Tracekit's remote fetching by default | ||
TK.remoteFetching = false; | ||
/* | ||
@@ -1170,6 +1153,6 @@ * The core Raven singleton | ||
var Raven = { | ||
VERSION: '1.1.3', | ||
VERSION: '1.1.11', | ||
// Expose TraceKit to the Raven namespace | ||
TraceKit: TK, | ||
TraceKit: TraceKit, | ||
@@ -1208,2 +1191,4 @@ /* | ||
config: function(dsn, options) { | ||
if (!dsn) return Raven; | ||
var uri = parseDSN(dsn), | ||
@@ -1232,3 +1217,3 @@ lastSlash = uri.path.lastIndexOf('/'), | ||
globalKey = uri.user; | ||
globalProject = ~~uri.path.substr(lastSlash + 1); | ||
globalProject = uri.path.substr(lastSlash + 1); | ||
@@ -1245,10 +1230,10 @@ // assemble the endpoint from the uri pieces | ||
if (globalOptions.fetchContext) { | ||
TK.remoteFetching = true; | ||
TraceKit.remoteFetching = true; | ||
} | ||
if (globalOptions.linesOfContext) { | ||
TK.linesOfContext = globalOptions.linesOfContext; | ||
TraceKit.linesOfContext = globalOptions.linesOfContext; | ||
} | ||
TK.collectWindowErrors = !!globalOptions.collectWindowErrors; | ||
TraceKit.collectWindowErrors = !!globalOptions.collectWindowErrors; | ||
@@ -1269,3 +1254,3 @@ // return for chaining | ||
if (isSetup()) { | ||
TK.report.subscribe(handleStackInfo); | ||
TraceKit.report.subscribe(handleStackInfo); | ||
} | ||
@@ -1326,6 +1311,9 @@ | ||
function wrapped() { | ||
var args = [], i = arguments.length; | ||
var args = [], i = arguments.length, | ||
deep = !options || options && options.deep !== false; | ||
// Recursively wrap all of a function's arguments that are | ||
// functions themselves. | ||
while(i--) args[i] = Raven.wrap(options, arguments[i]); | ||
while(i--) args[i] = deep ? Raven.wrap(options, arguments[i]) : arguments[i]; | ||
try { | ||
@@ -1360,3 +1348,3 @@ /*jshint -W040*/ | ||
uninstall: function() { | ||
TK.report.unsubscribe(handleStackInfo); | ||
TraceKit.report.uninstall(); | ||
@@ -1386,3 +1374,3 @@ return Raven; | ||
try { | ||
TK.report(ex, options); | ||
TraceKit.report(ex, options); | ||
} catch(ex1) { | ||
@@ -1407,3 +1395,3 @@ if(ex !== ex1) { | ||
send( | ||
arrayMerge({ | ||
objectMerge({ | ||
message: msg | ||
@@ -1435,2 +1423,11 @@ }, options) | ||
return lastCapturedException; | ||
}, | ||
/* | ||
* Get the last event id | ||
* | ||
* @return {string} | ||
*/ | ||
lastEventId: function() { | ||
return lastEventId; | ||
} | ||
@@ -1510,2 +1507,18 @@ }; | ||
function isEmptyObject(what) { | ||
for (var k in what) return false; | ||
return true; | ||
} | ||
/** | ||
* hasKey, a better form of hasOwnProperty | ||
* Example: hasKey(MainHostObject, property) === true/false | ||
* | ||
* @param {Object} host object to check property | ||
* @param {string} key to check | ||
*/ | ||
function hasKey(object, key) { | ||
return Object.prototype.hasOwnProperty.call(object, key); | ||
} | ||
function each(obj, callback) { | ||
@@ -1655,4 +1668,7 @@ var i, j; | ||
if (frames && frames.length) { | ||
fileurl = frames[0].filename || fileurl; | ||
// Sentry expects frames oldest to newest | ||
// and JS sends them as newest to oldest | ||
frames.reverse(); | ||
stacktrace = {frames: frames}; | ||
fileurl = fileurl || frames[0].filename; | ||
} else if (fileurl) { | ||
@@ -1674,3 +1690,3 @@ stacktrace = { | ||
send( | ||
arrayMerge({ | ||
objectMerge({ | ||
// sentry.interfaces.Exception | ||
@@ -1689,10 +1705,10 @@ exception: { | ||
function arrayMerge(arr1, arr2) { | ||
if (!arr2) { | ||
return arr1; | ||
function objectMerge(obj1, obj2) { | ||
if (!obj2) { | ||
return obj1; | ||
} | ||
each(arr2, function(key, value){ | ||
arr1[key] = value; | ||
each(obj2, function(key, value){ | ||
obj1[key] = value; | ||
}); | ||
return arr1; | ||
return obj1; | ||
} | ||
@@ -1718,3 +1734,3 @@ | ||
data = arrayMerge({ | ||
data = objectMerge({ | ||
project: globalProject, | ||
@@ -1728,9 +1744,9 @@ logger: globalOptions.logger, | ||
// Merge in the tags and extra separately since arrayMerge doesn't handle a deep merge | ||
data.tags = arrayMerge(globalOptions.tags, data.tags); | ||
data.extra = arrayMerge(globalOptions.extra, data.extra); | ||
// Merge in the tags and extra separately since objectMerge doesn't handle a deep merge | ||
data.tags = objectMerge(globalOptions.tags, data.tags); | ||
data.extra = objectMerge(globalOptions.extra, data.extra); | ||
// If there are no tags/extra, strip the key from the payload alltogther. | ||
if (!data.tags) delete data.tags; | ||
if (!data.extra) delete data.extra; | ||
if (isEmptyObject(data.tags)) delete data.tags; | ||
if (isEmptyObject(data.extra)) delete data.extra; | ||
@@ -1751,2 +1767,7 @@ if (globalUser) { | ||
// Send along an event_id if not explicitly passed. | ||
// This event_id can be used to reference the error within Sentry itself. | ||
// Set lastEventId after we know the error should actually be sent | ||
lastEventId = data.event_id || (data.event_id = generateUUID4()); | ||
makeRequest(data); | ||
@@ -1789,10 +1810,17 @@ } | ||
// Be mad. | ||
var sources = [], i = patterns.length; | ||
while (i--) { | ||
sources[i] = isString(patterns[i]) ? | ||
var sources = [], | ||
i = 0, len = patterns.length, | ||
pattern; | ||
for (; i < len; i++) { | ||
pattern = patterns[i]; | ||
if (isString(pattern)) { | ||
// If it's a string, we need to escape it | ||
// Taken from: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions | ||
patterns[i].replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1") : | ||
sources.push(pattern.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1")); | ||
} else if (pattern && pattern.source) { | ||
// If it's a regexp already, we want to extract the source | ||
patterns[i].source; | ||
sources.push(pattern.source); | ||
} | ||
// Intentionally skip other cases | ||
} | ||
@@ -1802,2 +1830,11 @@ return new RegExp(sources.join('|'), 'i'); | ||
// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523 | ||
function generateUUID4() { | ||
return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) { | ||
var r = Math.random()*16|0, | ||
v = c == 'x' ? r : (r&0x3|0x8); | ||
return v.toString(16); | ||
}); | ||
} | ||
Raven.afterLoad(); | ||
@@ -1804,0 +1841,0 @@ |
@@ -1,3 +0,3 @@ | ||
/*! Raven.js 1.1.3 (d81942a) | github.com/getsentry/raven-js */ | ||
!function(a){function b(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function c(a){return"undefined"==typeof a}var d={},e=a.TraceKit,f=[].slice,g="?";d.noConflict=function(){return a.TraceKit=e,d},d.wrap=function(a){function b(){try{return a.apply(this,arguments)}catch(b){throw d.report(b),b}}return b},d.report=function(){function c(a){i(),m.push(a)}function e(a){for(var b=m.length-1;b>=0;--b)m[b]===a&&m.splice(b,1)}function g(a,c){var e=null;if(!c||d.collectWindowErrors){for(var g in m)if(b(m,g))try{m[g].apply(null,[a].concat(f.call(arguments,2)))}catch(h){e=h}if(e)throw e}}function h(a,b,c){var e=null;if(o)d.computeStackTrace.augmentStackTraceWithInitialElement(o,b,c,a),e=o,o=null,n=null;else{var f={url:b,line:c};f.func=d.computeStackTrace.guessFunctionName(f.url,f.line),f.context=d.computeStackTrace.gatherContext(f.url,f.line),e={mode:"onerror",message:a,url:document.location.href,stack:[f],useragent:navigator.userAgent}}return g(e,"from window.onerror"),k?k.apply(this,arguments):!1}function i(){l!==!0&&(k=a.onerror,a.onerror=h,l=!0)}function j(b){var c=f.call(arguments,1);if(o){if(n===b)return;var e=o;o=null,n=null,g.apply(null,[e,null].concat(c))}var h=d.computeStackTrace(b);throw o=h,n=b,a.setTimeout(function(){n===b&&(o=null,n=null,g.apply(null,[h,null].concat(c)))},h.incomplete?2e3:0),b}var k,l,m=[],n=null,o=null;return j.subscribe=c,j.unsubscribe=e,j}(),d.computeStackTrace=function(){function e(b){function c(){try{return new a.XMLHttpRequest}catch(b){return new a.ActiveXObject("Microsoft.XMLHTTP")}}if(!d.remoteFetching)return"";try{var e=c();return e.open("GET",b,!1),e.send(""),e.responseText}catch(f){return""}}function f(a){if(!b(w,a)){var c="";-1!==a.indexOf(document.domain)&&(c=e(a)),w[a]=c?c.split("\n"):[]}return w[a]}function h(a,b){var d,e=/function ([^(]*)\(([^)]*)\)/,h=/['"]?([0-9A-Za-z$_]+)['"]?\s*[:=]\s*(function|eval|new Function)/,i="",j=10,k=f(a);if(!k.length)return g;for(var l=0;j>l;++l)if(i=k[b-l]+i,!c(i)){if(d=h.exec(i))return d[1];if(d=e.exec(i))return d[1]}return g}function i(a,b){var e=f(a);if(!e.length)return null;var g=[],h=Math.floor(d.linesOfContext/2),i=h+d.linesOfContext%2,j=Math.max(0,b-h-1),k=Math.min(e.length,b+i-1);b-=1;for(var l=j;k>l;++l)c(e[l])||g.push(e[l]);return g.length>0?g:null}function j(a){return a.replace(/[\-\[\]{}()*+?.,\\\^$|#]/g,"\\$&")}function k(a){return j(a).replace("<","(?:<|<)").replace(">","(?:>|>)").replace("&","(?:&|&)").replace('"','(?:"|")').replace(/\s+/g,"\\s+")}function l(a,b){for(var c,d,e=0,g=b.length;g>e;++e)if((c=f(b[e])).length&&(c=c.join("\n"),d=a.exec(c)))return{url:b[e],line:c.substring(0,d.index).split("\n").length,column:d.index-c.lastIndexOf("\n",d.index)-1};return null}function m(a,b,c){var d,e=f(b),g=new RegExp("\\b"+j(a)+"\\b");return c-=1,e&&e.length>c&&(d=g.exec(e[c]))?d.index:null}function n(b){for(var c,d,e,f,g=[a.location.href],h=document.getElementsByTagName("script"),i=""+b,m=/^function(?:\s+([\w$]+))?\s*\(([\w\s,]*)\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/,n=/^function on([\w$]+)\s*\(event\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/,o=0;o<h.length;++o){var p=h[o];p.src&&g.push(p.src)}if(e=m.exec(i)){var q=e[1]?"\\s+"+e[1]:"",r=e[2].split(",").join("\\s*,\\s*");c=j(e[3]).replace(/;$/,";?"),d=new RegExp("function"+q+"\\s*\\(\\s*"+r+"\\s*\\)\\s*{\\s*"+c+"\\s*}")}else d=new RegExp(j(i).replace(/\s+/g,"\\s+"));if(f=l(d,g))return f;if(e=n.exec(i)){var s=e[1];if(c=k(e[2]),d=new RegExp("on"+s+"=[\\'\"]\\s*"+c+"\\s*[\\'\"]","i"),f=l(d,g[0]))return f;if(d=new RegExp(c),f=l(d,g))return f}return null}function o(a){if(!a.stack)return null;for(var b,c,d=/^\s*at (?:((?:\[object object\])?\S+) )?\(?((?:file|http|https):.*?):(\d+)(?::(\d+))?\)?\s*$/i,e=/^\s*(\S*)(?:\((.*?)\))?@((?:file|http|https).*?):(\d+)(?::(\d+))?\s*$/i,f=a.stack.split("\n"),j=[],k=/^(.*) is undefined$/.exec(a.message),l=0,n=f.length;n>l;++l){if(b=e.exec(f[l]))c={url:b[3],func:b[1]||g,args:b[2]?b[2].split(","):"",line:+b[4],column:b[5]?+b[5]:null};else{if(!(b=d.exec(f[l])))continue;c={url:b[2],func:b[1]||g,line:+b[3],column:b[4]?+b[4]:null}}!c.func&&c.line&&(c.func=h(c.url,c.line)),c.line&&(c.context=i(c.url,c.line)),j.push(c)}return j[0]&&j[0].line&&!j[0].column&&k&&(j[0].column=m(k[1],j[0].url,j[0].line)),j.length?{mode:"stack",name:a.name,message:a.message,url:document.location.href,stack:j,useragent:navigator.userAgent}:null}function p(a){for(var b,c=a.stacktrace,d=/ line (\d+), column (\d+) in (?:<anonymous function: ([^>]+)>|([^\)]+))\((.*)\) in (.*):\s*$/i,e=c.split("\n"),f=[],g=0,j=e.length;j>g;g+=2)if(b=d.exec(e[g])){var k={line:+b[1],column:+b[2],func:b[3]||b[4],args:b[5]?b[5].split(","):[],url:b[6]};if(!k.func&&k.line&&(k.func=h(k.url,k.line)),k.line)try{k.context=i(k.url,k.line)}catch(l){}k.context||(k.context=[e[g+1]]),f.push(k)}return f.length?{mode:"stacktrace",name:a.name,message:a.message,url:document.location.href,stack:f,useragent:navigator.userAgent}:null}function q(c){var d=c.message.split("\n");if(d.length<4)return null;var e,g,j,m,n=/^\s*Line (\d+) of linked script ((?:file|http|https)\S+)(?:: in function (\S+))?\s*$/i,o=/^\s*Line (\d+) of inline#(\d+) script in ((?:file|http|https)\S+)(?:: in function (\S+))?\s*$/i,p=/^\s*Line (\d+) of function script\s*$/i,q=[],r=document.getElementsByTagName("script"),s=[];for(g in r)b(r,g)&&!r[g].src&&s.push(r[g]);for(g=2,j=d.length;j>g;g+=2){var t=null;if(e=n.exec(d[g]))t={url:e[2],func:e[3],line:+e[1]};else if(e=o.exec(d[g])){t={url:e[3],func:e[4]};var u=+e[1],v=s[e[2]-1];if(v&&(m=f(t.url))){m=m.join("\n");var w=m.indexOf(v.innerText);w>=0&&(t.line=u+m.substring(0,w).split("\n").length)}}else if(e=p.exec(d[g])){var x=a.location.href.replace(/#.*$/,""),y=e[1],z=new RegExp(k(d[g+1]));m=l(z,[x]),t={url:x,line:m?m.line:y,func:""}}if(t){t.func||(t.func=h(t.url,t.line));var A=i(t.url,t.line),B=A?A[Math.floor(A.length/2)]:null;t.context=A&&B.replace(/^\s*/,"")===d[g+1].replace(/^\s*/,"")?A:[d[g+1]],q.push(t)}}return q.length?{mode:"multiline",name:c.name,message:d[0],url:document.location.href,stack:q,useragent:navigator.userAgent}:null}function r(a,b,c,d){var e={url:b,line:c};if(e.url&&e.line){a.incomplete=!1,e.func||(e.func=h(e.url,e.line)),e.context||(e.context=i(e.url,e.line));var f=/ '([^']+)' /.exec(d);if(f&&(e.column=m(f[1],e.url,e.line)),a.stack.length>0&&a.stack[0].url===e.url){if(a.stack[0].line===e.line)return!1;if(!a.stack[0].line&&a.stack[0].func===e.func)return a.stack[0].line=e.line,a.stack[0].context=e.context,!1}return a.stack.unshift(e),a.partial=!0,!0}return a.incomplete=!0,!1}function s(a,b){for(var c,e,f,i=/function\s+([_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)?\s*\(/i,j=[],k={},l=!1,o=s.caller;o&&!l;o=o.caller)if(o!==t&&o!==d.report){if(e={url:null,func:g,line:null,column:null},o.name?e.func=o.name:(c=i.exec(o.toString()))&&(e.func=c[1]),f=n(o)){e.url=f.url,e.line=f.line,e.func===g&&(e.func=h(e.url,e.line));var p=/ '([^']+)' /.exec(a.message||a.description);p&&(e.column=m(p[1],f.url,f.line))}k[""+o]?l=!0:k[""+o]=!0,j.push(e)}b&&j.splice(0,b);var q={mode:"callers",name:a.name,message:a.message,url:document.location.href,stack:j,useragent:navigator.userAgent};return r(q,a.sourceURL||a.fileName,a.line||a.lineNumber,a.message||a.description),q}function t(a,b){var c=null;b=null==b?0:+b;try{if(c=p(a))return c}catch(d){if(v)throw d}try{if(c=o(a))return c}catch(d){if(v)throw d}try{if(c=q(a))return c}catch(d){if(v)throw d}try{if(c=s(a,b+1))return c}catch(d){if(v)throw d}return{mode:"failed"}}function u(a){a=(null==a?0:+a)+1;try{throw new Error}catch(b){return t(b,a+1)}return null}var v=!1,w={};return t.augmentStackTraceWithInitialElement=r,t.guessFunctionName=h,t.gatherContext=i,t.ofCaller=u,t}(),d.remoteFetching||(d.remoteFetching=!0),d.collectWindowErrors||(d.collectWindowErrors=!0),(!d.linesOfContext||d.linesOfContext<1)&&(d.linesOfContext=7),a.TraceKit=d}(window),function(a,b){"use strict";function c(a,b){var c,d;b=b||{},a="raven"+a.substr(0,1).toUpperCase()+a.substr(1),document.createEvent?(c=document.createEvent("HTMLEvents"),c.initEvent(a,!0,!0)):(c=document.createEventObject(),c.eventType=a);for(d in b)b.hasOwnProperty(d)&&(c[d]=b[d]);if(document.createEvent)document.dispatchEvent(c);else try{document.fireEvent("on"+c.eventType.toLowerCase(),c)}catch(e){}}function d(a){this.name="RavenConfigError",this.message=a}function e(a){var b=F.exec(a),c={},e=7;try{for(;e--;)c[E[e]]=b[e]||""}catch(f){throw new d("Invalid DSN: "+a)}if(c.pass)throw new d("Do not specify your private key in the DSN!");return c}function f(a){return"undefined"==typeof a}function g(a){return"function"==typeof a}function h(a){return"string"==typeof a}function i(a,b){var c,d;if(f(a.length))for(c in a)a.hasOwnProperty(c)&&b.call(null,c,a[c]);else if(d=a.length)for(c=0;d>c;c++)b.call(null,c,a[c])}function j(){if(G)return G;var a=["sentry_version=4","sentry_client=raven-js/"+D.VERSION];return x&&a.push("sentry_key="+x),G="?"+a.join("&")}function k(a,b){var d=[];a.stack&&a.stack.length&&i(a.stack,function(a,b){var c=l(b);c&&d.push(c)}),c("handle",{stackInfo:a,options:b}),n(a.name,a.message,a.url,a.lineno,d,b)}function l(a){if(a.url){var b,c={filename:a.url,lineno:a.line,colno:a.column,"function":a.func||"?"},d=m(a);if(d){var e=["pre_context","context_line","post_context"];for(b=3;b--;)c[e[b]]=d[b]}return c.in_app=!(!B.includePaths.test(c.filename)||/(Raven|TraceKit)\./.test(c["function"])||/raven\.(min\.)js$/.test(c.filename)),c}}function m(a){if(a.context&&B.fetchContext){for(var b=a.context,c=~~(b.length/2),d=b.length,e=!1;d--;)if(b[d].length>300){e=!0;break}if(e){if(f(a.column))return;return[[],b[c].substr(a.column,50),[]]}return[b.slice(0,c),b[c],b.slice(c+1)]}}function n(a,b,c,d,e,f){var g,h;b&&(B.ignoreErrors.test(b)||(e&&e.length?(g={frames:e},c=c||e[0].filename):c&&(g={frames:[{filename:c,lineno:d}]}),B.ignoreUrls&&B.ignoreUrls.test(c)||(!B.whitelistUrls||B.whitelistUrls.test(c))&&(h=d?b+" at "+d:b,q(o({exception:{type:a,value:b},stacktrace:g,culprit:c,message:h},f)))))}function o(a,b){return b?(i(b,function(b,c){a[b]=c}),a):a}function p(){var a={url:document.location.href,headers:{"User-Agent":navigator.userAgent}};return document.referrer&&(a.headers.Referer=document.referrer),a}function q(a){s()&&(a=o({project:y,logger:B.logger,site:B.site,platform:"javascript",request:p()},a),a.tags=o(B.tags,a.tags),a.extra=o(B.extra,a.extra),a.tags||delete a.tags,a.extra||delete a.extra,w&&(a.user=w),g(B.dataCallback)&&(a=B.dataCallback(a)),(!g(B.shouldSendCallback)||B.shouldSendCallback(a))&&r(a))}function r(a){var b=new Image,d=v+j()+"&sentry_data="+encodeURIComponent(JSON.stringify(a));b.onload=function(){c("success",{data:a,src:d})},b.onerror=b.onabort=function(){c("failure",{data:a,src:d})},b.src=d}function s(){return A?v?!0:(a.console&&console.error&&console.error("Error: Raven has not been configured."),!1):!1}function t(a){for(var b=[],c=a.length;c--;)b[c]=h(a[c])?a[c].replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1"):a[c].source;return new RegExp(b.join("|"),"i")}var u,v,w,x,y,z=a.Raven,A=!(!a.JSON||!a.JSON.stringify),B={logger:"javascript",ignoreErrors:[],ignoreUrls:[],whitelistUrls:[],includePaths:[],collectWindowErrors:!0,tags:{},extra:{}},C=TraceKit.noConflict();C.remoteFetching=!1;var D={VERSION:"1.1.3",TraceKit:C,afterLoad:function(){var b=a.RavenConfig;b&&this.config(b.dsn,b.config).install()},noConflict:function(){return a.Raven=z,D},config:function(a,b){var c=e(a),d=c.path.lastIndexOf("/"),f=c.path.substr(1,d);return b&&i(b,function(a,b){B[a]=b}),B.ignoreErrors.push("Script error."),B.ignoreErrors.push("Script error"),B.ignoreErrors=t(B.ignoreErrors),B.ignoreUrls=B.ignoreUrls.length?t(B.ignoreUrls):!1,B.whitelistUrls=B.whitelistUrls.length?t(B.whitelistUrls):!1,B.includePaths=t(B.includePaths),x=c.user,y=~~c.path.substr(d+1),v="//"+c.host+(c.port?":"+c.port:"")+"/"+f+"api/"+y+"/store/",c.protocol&&(v=c.protocol+":"+v),B.fetchContext&&(C.remoteFetching=!0),B.linesOfContext&&(C.linesOfContext=B.linesOfContext),C.collectWindowErrors=!!B.collectWindowErrors,D},install:function(){return s()&&C.report.subscribe(k),D},context:function(a,c,d){return g(a)&&(d=c||[],c=a,a=b),D.wrap(a,c).apply(this,d)},wrap:function(a,c){function d(){for(var b=[],d=arguments.length;d--;)b[d]=D.wrap(a,arguments[d]);try{return c.apply(this,b)}catch(e){throw D.captureException(e,a),e}}if(f(c)&&!g(a))return a;if(g(a)&&(c=a,a=b),!g(c))return c;if(c.__raven__)return c;for(var e in c)c.hasOwnProperty(e)&&(d[e]=c[e]);return d.__raven__=!0,d},uninstall:function(){return C.report.unsubscribe(k),D},captureException:function(a,b){if(h(a))return D.captureMessage(a,b);u=a;try{C.report(a,b)}catch(c){if(a!==c)throw c}return D},captureMessage:function(a,b){return q(o({message:a},b)),D},setUser:function(a){return w=a,D},lastException:function(){return u}},E="source protocol user pass host port path".split(" "),F=/^(?:(\w+):)?\/\/(\w+)(:\w+)?@([\w\.-]+)(?::(\d+))?(\/.*)/;d.prototype=new Error,d.prototype.constructor=d;var G;D.afterLoad(),a.Raven=D,"function"==typeof define&&define.amd&&define("raven",[],function(){return D})}(window); | ||
/*! Raven.js 1.1.11 (11645a0) | github.com/getsentry/raven-js */ | ||
!function(a,b){"use strict";function c(a,b){var c,d;b=b||{},a="raven"+a.substr(0,1).toUpperCase()+a.substr(1),document.createEvent?(c=document.createEvent("HTMLEvents"),c.initEvent(a,!0,!0)):(c=document.createEventObject(),c.eventType=a);for(d in b)b.hasOwnProperty(d)&&(c[d]=b[d]);if(document.createEvent)document.dispatchEvent(c);else try{document.fireEvent("on"+c.eventType.toLowerCase(),c)}catch(e){}}function d(a){this.name="RavenConfigError",this.message=a}function e(a){var b=L.exec(a),c={},e=7;try{for(;e--;)c[K[e]]=b[e]||""}catch(f){throw new d("Invalid DSN: "+a)}if(c.pass)throw new d("Do not specify your private key in the DSN!");return c}function f(a){return"undefined"==typeof a}function g(a){return"function"==typeof a}function h(a){return"string"==typeof a}function i(a){for(var b in a)return!1;return!0}function j(a,b){return Object.prototype.hasOwnProperty.call(a,b)}function k(a,b){var c,d;if(f(a.length))for(c in a)a.hasOwnProperty(c)&&b.call(null,c,a[c]);else if(d=a.length)for(c=0;d>c;c++)b.call(null,c,a[c])}function l(){if(M)return M;var a=["sentry_version=4","sentry_client=raven-js/"+J.VERSION];return E&&a.push("sentry_key="+E),M="?"+a.join("&")}function m(a,b){var d=[];a.stack&&a.stack.length&&k(a.stack,function(a,b){var c=n(b);c&&d.push(c)}),c("handle",{stackInfo:a,options:b}),p(a.name,a.message,a.url,a.lineno,d,b)}function n(a){if(a.url){var b,c={filename:a.url,lineno:a.line,colno:a.column,"function":a.func||"?"},d=o(a);if(d){var e=["pre_context","context_line","post_context"];for(b=3;b--;)c[e[b]]=d[b]}return c.in_app=!(!I.includePaths.test(c.filename)||/(Raven|TraceKit)\./.test(c["function"])||/raven\.(min\.)js$/.test(c.filename)),c}}function o(a){if(a.context&&I.fetchContext){for(var b=a.context,c=~~(b.length/2),d=b.length,e=!1;d--;)if(b[d].length>300){e=!0;break}if(e){if(f(a.column))return;return[[],b[c].substr(a.column,50),[]]}return[b.slice(0,c),b[c],b.slice(c+1)]}}function p(a,b,c,d,e,f){var g,h;b&&(I.ignoreErrors.test(b)||(e&&e.length?(c=e[0].filename||c,e.reverse(),g={frames:e}):c&&(g={frames:[{filename:c,lineno:d}]}),I.ignoreUrls&&I.ignoreUrls.test(c)||(!I.whitelistUrls||I.whitelistUrls.test(c))&&(h=d?b+" at "+d:b,s(q({exception:{type:a,value:b},stacktrace:g,culprit:c,message:h},f)))))}function q(a,b){return b?(k(b,function(b,c){a[b]=c}),a):a}function r(){var a={url:document.location.href,headers:{"User-Agent":navigator.userAgent}};return document.referrer&&(a.headers.Referer=document.referrer),a}function s(a){u()&&(a=q({project:F,logger:I.logger,site:I.site,platform:"javascript",request:r()},a),a.tags=q(I.tags,a.tags),a.extra=q(I.extra,a.extra),i(a.tags)&&delete a.tags,i(a.extra)&&delete a.extra,D&&(a.user=D),g(I.dataCallback)&&(a=I.dataCallback(a)),(!g(I.shouldSendCallback)||I.shouldSendCallback(a))&&(B=a.event_id||(a.event_id=w()),t(a)))}function t(a){var b=new Image,d=C+l()+"&sentry_data="+encodeURIComponent(JSON.stringify(a));b.onload=function(){c("success",{data:a,src:d})},b.onerror=b.onabort=function(){c("failure",{data:a,src:d})},b.src=d}function u(){return H?C?!0:(a.console&&console.error&&console.error("Error: Raven has not been configured."),!1):!1}function v(a){for(var b,c=[],d=0,e=a.length;e>d;d++)b=a[d],h(b)?c.push(b.replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")):b&&b.source&&c.push(b.source);return new RegExp(c.join("|"),"i")}function w(){return"xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=16*Math.random()|0,c="x"==a?b:3&b|8;return c.toString(16)})}var x={remoteFetching:!1,collectWindowErrors:!0,linesOfContext:7},y=[].slice,z="?";x.wrap=function(a){function b(){try{return a.apply(this,arguments)}catch(b){throw x.report(b),b}}return b},x.report=function(){function c(a){h(),o.push(a)}function d(a){for(var b=o.length-1;b>=0;--b)o[b]===a&&o.splice(b,1)}function e(){i(),o=[]}function f(a,b){var c=null;if(!b||x.collectWindowErrors){for(var d in o)if(j(o,d))try{o[d].apply(null,[a].concat(y.call(arguments,2)))}catch(e){c=e}if(c)throw c}}function g(a,b,c,d,e){var g=null;if(r)x.computeStackTrace.augmentStackTraceWithInitialElement(r,b,c,a),k();else if(e)g=x.computeStackTrace(e),f(g,!0);else{var h={url:b,line:c,column:d};h.func=x.computeStackTrace.guessFunctionName(h.url,h.line),h.context=x.computeStackTrace.gatherContext(h.url,h.line),g={message:a,url:document.location.href,stack:[h]},f(g,!0)}return m?m.apply(this,arguments):!1}function h(){n||(m=a.onerror,a.onerror=g,n=!0)}function i(){n&&(a.onerror=m,n=!1,m=b)}function k(){var a=r,b=p;p=null,r=null,q=null,f.apply(null,[a,!1].concat(b))}function l(b,c){var d=y.call(arguments,1);if(r){if(q===b)return;k()}var e=x.computeStackTrace(b);if(r=e,q=b,p=d,a.setTimeout(function(){q===b&&k()},e.incomplete?2e3:0),c!==!1)throw b}var m,n,o=[],p=null,q=null,r=null;return l.subscribe=c,l.unsubscribe=d,l.uninstall=e,l}(),x.computeStackTrace=function(){function b(b){if(!x.remoteFetching)return"";try{var c=function(){try{return new a.XMLHttpRequest}catch(b){return new a.ActiveXObject("Microsoft.XMLHTTP")}},d=c();return d.open("GET",b,!1),d.send(""),d.responseText}catch(e){return""}}function c(a){if(!h(a))return[];if(!j(v,a)){var c="";-1!==a.indexOf(document.domain)&&(c=b(a)),v[a]=c?c.split("\n"):[]}return v[a]}function d(a,b){var d,e=/function ([^(]*)\(([^)]*)\)/,g=/['"]?([0-9A-Za-z$_]+)['"]?\s*[:=]\s*(function|eval|new Function)/,h="",i=10,j=c(a);if(!j.length)return z;for(var k=0;i>k;++k)if(h=j[b-k]+h,!f(h)){if(d=g.exec(h))return d[1];if(d=e.exec(h))return d[1]}return z}function e(a,b){var d=c(a);if(!d.length)return null;var e=[],g=Math.floor(x.linesOfContext/2),h=g+x.linesOfContext%2,i=Math.max(0,b-g-1),j=Math.min(d.length,b+h-1);b-=1;for(var k=i;j>k;++k)f(d[k])||e.push(d[k]);return e.length>0?e:null}function g(a){return a.replace(/[\-\[\]{}()*+?.,\\\^$|#]/g,"\\$&")}function i(a){return g(a).replace("<","(?:<|<)").replace(">","(?:>|>)").replace("&","(?:&|&)").replace('"','(?:"|")').replace(/\s+/g,"\\s+")}function k(a,b){for(var d,e,f=0,g=b.length;g>f;++f)if((d=c(b[f])).length&&(d=d.join("\n"),e=a.exec(d)))return{url:b[f],line:d.substring(0,e.index).split("\n").length,column:e.index-d.lastIndexOf("\n",e.index)-1};return null}function l(a,b,d){var e,f=c(b),h=new RegExp("\\b"+g(a)+"\\b");return d-=1,f&&f.length>d&&(e=h.exec(f[d]))?e.index:null}function m(b){for(var c,d,e,f,h=[a.location.href],j=document.getElementsByTagName("script"),l=""+b,m=/^function(?:\s+([\w$]+))?\s*\(([\w\s,]*)\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/,n=/^function on([\w$]+)\s*\(event\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/,o=0;o<j.length;++o){var p=j[o];p.src&&h.push(p.src)}if(e=m.exec(l)){var q=e[1]?"\\s+"+e[1]:"",r=e[2].split(",").join("\\s*,\\s*");c=g(e[3]).replace(/;$/,";?"),d=new RegExp("function"+q+"\\s*\\(\\s*"+r+"\\s*\\)\\s*{\\s*"+c+"\\s*}")}else d=new RegExp(g(l).replace(/\s+/g,"\\s+"));if(f=k(d,h))return f;if(e=n.exec(l)){var s=e[1];if(c=i(e[2]),d=new RegExp("on"+s+"=[\\'\"]\\s*"+c+"\\s*[\\'\"]","i"),f=k(d,h[0]))return f;if(d=new RegExp(c),f=k(d,h))return f}return null}function n(a){if(!a.stack)return null;for(var b,c,g=/^\s*at (?:((?:\[object object\])?\S+(?: \[as \S+\])?) )?\(?((?:file|https?):.*?):(\d+)(?::(\d+))?\)?\s*$/i,h=/^\s*(\S*)(?:\((.*?)\))?@((?:file|https?).*?):(\d+)(?::(\d+))?\s*$/i,i=a.stack.split("\n"),j=[],k=/^(.*) is undefined$/.exec(a.message),m=0,n=i.length;n>m;++m){if(b=h.exec(i[m]))c={url:b[3],func:b[1]||z,args:b[2]?b[2].split(","):"",line:+b[4],column:b[5]?+b[5]:null};else{if(!(b=g.exec(i[m])))continue;c={url:b[2],func:b[1]||z,line:+b[3],column:b[4]?+b[4]:null}}!c.func&&c.line&&(c.func=d(c.url,c.line)),c.line&&(c.context=e(c.url,c.line)),j.push(c)}return j.length?(j[0].line&&!j[0].column&&k?j[0].column=l(k[1],j[0].url,j[0].line):j[0].column||f(a.columnNumber)||(j[0].column=a.columnNumber+1),{name:a.name,message:a.message,url:document.location.href,stack:j}):null}function o(a){for(var b,c=a.stacktrace,f=/ line (\d+), column (\d+) in (?:<anonymous function: ([^>]+)>|([^\)]+))\((.*)\) in (.*):\s*$/i,g=c.split("\n"),h=[],i=0,j=g.length;j>i;i+=2)if(b=f.exec(g[i])){var k={line:+b[1],column:+b[2],func:b[3]||b[4],args:b[5]?b[5].split(","):[],url:b[6]};if(!k.func&&k.line&&(k.func=d(k.url,k.line)),k.line)try{k.context=e(k.url,k.line)}catch(l){}k.context||(k.context=[g[i+1]]),h.push(k)}return h.length?{name:a.name,message:a.message,url:document.location.href,stack:h}:null}function p(b){var f=b.message.split("\n");if(f.length<4)return null;var g,h,l,m,n=/^\s*Line (\d+) of linked script ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i,o=/^\s*Line (\d+) of inline#(\d+) script in ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i,p=/^\s*Line (\d+) of function script\s*$/i,q=[],r=document.getElementsByTagName("script"),s=[];for(h in r)j(r,h)&&!r[h].src&&s.push(r[h]);for(h=2,l=f.length;l>h;h+=2){var t=null;if(g=n.exec(f[h]))t={url:g[2],func:g[3],line:+g[1]};else if(g=o.exec(f[h])){t={url:g[3],func:g[4]};var u=+g[1],v=s[g[2]-1];if(v&&(m=c(t.url))){m=m.join("\n");var w=m.indexOf(v.innerText);w>=0&&(t.line=u+m.substring(0,w).split("\n").length)}}else if(g=p.exec(f[h])){var x=a.location.href.replace(/#.*$/,""),y=g[1],z=new RegExp(i(f[h+1]));m=k(z,[x]),t={url:x,line:m?m.line:y,func:""}}if(t){t.func||(t.func=d(t.url,t.line));var A=e(t.url,t.line),B=A?A[Math.floor(A.length/2)]:null;t.context=A&&B.replace(/^\s*/,"")===f[h+1].replace(/^\s*/,"")?A:[f[h+1]],q.push(t)}}return q.length?{name:b.name,message:f[0],url:document.location.href,stack:q}:null}function q(a,b,c,f){var g={url:b,line:c};if(g.url&&g.line){a.incomplete=!1,g.func||(g.func=d(g.url,g.line)),g.context||(g.context=e(g.url,g.line));var h=/ '([^']+)' /.exec(f);if(h&&(g.column=l(h[1],g.url,g.line)),a.stack.length>0&&a.stack[0].url===g.url){if(a.stack[0].line===g.line)return!1;if(!a.stack[0].line&&a.stack[0].func===g.func)return a.stack[0].line=g.line,a.stack[0].context=g.context,!1}return a.stack.unshift(g),a.partial=!0,!0}return a.incomplete=!0,!1}function r(a,b){for(var c,e,f,g=/function\s+([_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)?\s*\(/i,h=[],i={},j=!1,k=r.caller;k&&!j;k=k.caller)if(k!==s&&k!==x.report){if(e={url:null,func:z,line:null,column:null},k.name?e.func=k.name:(c=g.exec(k.toString()))&&(e.func=c[1]),f=m(k)){e.url=f.url,e.line=f.line,e.func===z&&(e.func=d(e.url,e.line));var n=/ '([^']+)' /.exec(a.message||a.description);n&&(e.column=l(n[1],f.url,f.line))}i[""+k]?j=!0:i[""+k]=!0,h.push(e)}b&&h.splice(0,b);var o={name:a.name,message:a.message,url:document.location.href,stack:h};return q(o,a.sourceURL||a.fileName,a.line||a.lineNumber,a.message||a.description),o}function s(a,b){var c=null;b=null==b?0:+b;try{if(c=o(a))return c}catch(d){if(u)throw d}try{if(c=n(a))return c}catch(d){if(u)throw d}try{if(c=p(a))return c}catch(d){if(u)throw d}try{if(c=r(a,b+1))return c}catch(d){if(u)throw d}return{}}function t(a){a=(null==a?0:+a)+1;try{throw new Error}catch(b){return s(b,a+1)}}var u=!1,v={};return s.augmentStackTraceWithInitialElement=q,s.guessFunctionName=d,s.gatherContext=e,s.ofCaller=t,s}();var A,B,C,D,E,F,G=a.Raven,H=!(!a.JSON||!a.JSON.stringify),I={logger:"javascript",ignoreErrors:[],ignoreUrls:[],whitelistUrls:[],includePaths:[],collectWindowErrors:!0,tags:{},extra:{}},J={VERSION:"1.1.11",TraceKit:x,afterLoad:function(){var b=a.RavenConfig;b&&this.config(b.dsn,b.config).install()},noConflict:function(){return a.Raven=G,J},config:function(a,b){if(!a)return J;var c=e(a),d=c.path.lastIndexOf("/"),f=c.path.substr(1,d);return b&&k(b,function(a,b){I[a]=b}),I.ignoreErrors.push("Script error."),I.ignoreErrors.push("Script error"),I.ignoreErrors=v(I.ignoreErrors),I.ignoreUrls=I.ignoreUrls.length?v(I.ignoreUrls):!1,I.whitelistUrls=I.whitelistUrls.length?v(I.whitelistUrls):!1,I.includePaths=v(I.includePaths),E=c.user,F=c.path.substr(d+1),C="//"+c.host+(c.port?":"+c.port:"")+"/"+f+"api/"+F+"/store/",c.protocol&&(C=c.protocol+":"+C),I.fetchContext&&(x.remoteFetching=!0),I.linesOfContext&&(x.linesOfContext=I.linesOfContext),x.collectWindowErrors=!!I.collectWindowErrors,J},install:function(){return u()&&x.report.subscribe(m),J},context:function(a,c,d){return g(a)&&(d=c||[],c=a,a=b),J.wrap(a,c).apply(this,d)},wrap:function(a,c){function d(){for(var b=[],d=arguments.length,e=!a||a&&a.deep!==!1;d--;)b[d]=e?J.wrap(a,arguments[d]):arguments[d];try{return c.apply(this,b)}catch(f){throw J.captureException(f,a),f}}if(f(c)&&!g(a))return a;if(g(a)&&(c=a,a=b),!g(c))return c;if(c.__raven__)return c;for(var e in c)c.hasOwnProperty(e)&&(d[e]=c[e]);return d.__raven__=!0,d},uninstall:function(){return x.report.uninstall(),J},captureException:function(a,b){if(h(a))return J.captureMessage(a,b);A=a;try{x.report(a,b)}catch(c){if(a!==c)throw c}return J},captureMessage:function(a,b){return s(q({message:a},b)),J},setUser:function(a){return D=a,J},lastException:function(){return A},lastEventId:function(){return B}},K="source protocol user pass host port path".split(" "),L=/^(?:(\w+):)?\/\/(\w+)(:\w+)?@([\w\.-]+)(?::(\d+))?(\/.*)/;d.prototype=new Error,d.prototype.constructor=d;var M;J.afterLoad(),a.Raven=J,"function"==typeof define&&define.amd&&define("raven",[],function(){return J})}(window); | ||
//# sourceMappingURL=raven.min.map |
@@ -29,1 +29,11 @@ function foo() { | ||
} | ||
function derp() { | ||
fdas[0]; | ||
} | ||
function testOptions() { | ||
Raven.context({tags: {foo: 'bar'}}, function() { | ||
throw new Error('foo'); | ||
}); | ||
} |
@@ -8,4 +8,4 @@ module.exports = function(grunt) { | ||
var coreFiles = [ | ||
'template/_header.js', | ||
'vendor/**/*.js', | ||
'template/_header.js', | ||
'src/**/*.js', | ||
@@ -144,3 +144,3 @@ 'template/_footer.js' | ||
src: 'build/**/*', | ||
dest: '<%= pkg.version %>/', | ||
dest: '<%= pkg.release %>/', | ||
rel: 'build/' | ||
@@ -184,2 +184,13 @@ }] | ||
// Custom Grunt tasks | ||
grunt.registerTask('version', function() { | ||
var pkg = grunt.config.get('pkg'); | ||
if (grunt.option('dev')) { | ||
pkg.release = 'dev'; | ||
pkg.version = grunt.config.get('gitinfo').local.branch.current.shortSHA; | ||
} else { | ||
pkg.release = pkg.version; | ||
} | ||
grunt.config.set('pkg', pkg); | ||
}); | ||
grunt.registerMultiTask('fixSourceMaps', function () { | ||
@@ -223,4 +234,4 @@ this.files.forEach(function (f) { | ||
// Build tasks | ||
grunt.registerTask('build.core', ['clean', 'gitinfo', 'concat:core', 'uglify', 'fixSourceMaps']); | ||
grunt.registerTask('build.all', ['clean', 'gitinfo', 'concat:all', 'uglify', 'fixSourceMaps']); | ||
grunt.registerTask('build.core', ['clean', 'gitinfo', 'version', 'concat:core', 'uglify', 'fixSourceMaps']); | ||
grunt.registerTask('build.all', ['clean', 'gitinfo', 'version', 'concat:all', 'uglify', 'fixSourceMaps']); | ||
grunt.registerTask('build', ['build.all']); | ||
@@ -227,0 +238,0 @@ grunt.registerTask('dist', ['build.core', 'copy:dist']); |
{ | ||
"name": "raven-js", | ||
"version": "1.1.3", | ||
"version": "1.1.11", | ||
"main": "./src/raven.js", | ||
"author": "Matt Robenolt <matt@ydekproductions.com>", | ||
"scripts": { | ||
"test": "grunt test" | ||
"test": "./node_modules/.bin/grunt test" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/getsentry/raven-js.git" | ||
"url": "git://github.com/defunctzombie/raven-js.git" | ||
}, | ||
"dependencies": { | ||
"tracekit": "0.1.0" | ||
}, | ||
"devDependencies": { | ||
@@ -17,0 +13,0 @@ "chai": "~1.8.1", |
@@ -15,2 +15,3 @@ /** | ||
var logForGivenLevel = function(level) { | ||
var originalConsoleLevel = console[level]; | ||
return function () { | ||
@@ -21,4 +22,4 @@ var args = [].slice.call(arguments); | ||
// this fails for some browsers. :( | ||
if (originalConsole[level]) { | ||
originalConsole[level].apply(null, args); | ||
if (originalConsoleLevel) { | ||
originalConsoleLevel.apply(originalConsole, args); | ||
} | ||
@@ -25,0 +26,0 @@ }; |
@@ -13,1 +13,2 @@ # Raven.js | ||
* [IRC](irc://chat.freenode.net/sentry) (chat.freenode.net, #sentry) | ||
* Follow [@mattrobenolt](https://twitter.com/mattrobenolt) on Twitter for updates |
118
src/raven.js
'use strict'; | ||
var TK = require('tracekit'); | ||
var TraceKit = require('../vendor/TraceKit/tracekit'); | ||
var VERSION = '1.1.3'; | ||
// First, check for JSON support | ||
// If there is no JSON, we no-op the core features of Raven | ||
// since JSON is required to encode the payload | ||
var hasJSON = !!(window.JSON && window.JSON.stringify), | ||
var _Raven = window.Raven, | ||
hasJSON = !!(window.JSON && window.JSON.stringify), | ||
lastCapturedException, | ||
lastEventId, | ||
globalServer, | ||
@@ -27,5 +27,2 @@ globalUser, | ||
// Disable Tracekit's remote fetching by default | ||
TK.remoteFetching = false; | ||
/* | ||
@@ -37,6 +34,6 @@ * The core Raven singleton | ||
var Raven = { | ||
VERSION: VERSION, | ||
VERSION: '1.1.11', | ||
// Expose TraceKit to the Raven namespace | ||
TraceKit: TK, | ||
TraceKit: TraceKit, | ||
@@ -63,2 +60,3 @@ /* | ||
noConflict: function() { | ||
window.Raven = _Raven; | ||
return Raven; | ||
@@ -75,2 +73,4 @@ }, | ||
config: function(dsn, options) { | ||
if (!dsn) return Raven; | ||
var uri = parseDSN(dsn), | ||
@@ -99,3 +99,3 @@ lastSlash = uri.path.lastIndexOf('/'), | ||
globalKey = uri.user; | ||
globalProject = ~~uri.path.substr(lastSlash + 1); | ||
globalProject = uri.path.substr(lastSlash + 1); | ||
@@ -112,10 +112,10 @@ // assemble the endpoint from the uri pieces | ||
if (globalOptions.fetchContext) { | ||
TK.remoteFetching = true; | ||
TraceKit.remoteFetching = true; | ||
} | ||
if (globalOptions.linesOfContext) { | ||
TK.linesOfContext = globalOptions.linesOfContext; | ||
TraceKit.linesOfContext = globalOptions.linesOfContext; | ||
} | ||
TK.collectWindowErrors = !!globalOptions.collectWindowErrors; | ||
TraceKit.collectWindowErrors = !!globalOptions.collectWindowErrors; | ||
@@ -136,3 +136,3 @@ // return for chaining | ||
if (isSetup()) { | ||
TK.report.subscribe(handleStackInfo); | ||
TraceKit.report.subscribe(handleStackInfo); | ||
} | ||
@@ -193,6 +193,9 @@ | ||
function wrapped() { | ||
var args = [], i = arguments.length; | ||
var args = [], i = arguments.length, | ||
deep = !options || options && options.deep !== false; | ||
// Recursively wrap all of a function's arguments that are | ||
// functions themselves. | ||
while(i--) args[i] = Raven.wrap(options, arguments[i]); | ||
while(i--) args[i] = deep ? Raven.wrap(options, arguments[i]) : arguments[i]; | ||
try { | ||
@@ -227,3 +230,3 @@ /*jshint -W040*/ | ||
uninstall: function() { | ||
TK.report.unsubscribe(handleStackInfo); | ||
TraceKit.report.uninstall(); | ||
@@ -253,3 +256,3 @@ return Raven; | ||
try { | ||
TK.report(ex, options); | ||
TraceKit.report(ex, options); | ||
} catch(ex1) { | ||
@@ -274,3 +277,3 @@ if(ex !== ex1) { | ||
send( | ||
arrayMerge({ | ||
objectMerge({ | ||
message: msg | ||
@@ -302,2 +305,11 @@ }, options) | ||
return lastCapturedException; | ||
}, | ||
/* | ||
* Get the last event id | ||
* | ||
* @return {string} | ||
*/ | ||
lastEventId: function() { | ||
return lastEventId; | ||
} | ||
@@ -377,2 +389,7 @@ }; | ||
function isEmptyObject(what) { | ||
for (var k in what) return false; | ||
return true; | ||
} | ||
function each(obj, callback) { | ||
@@ -522,4 +539,7 @@ var i, j; | ||
if (frames && frames.length) { | ||
fileurl = frames[0].filename || fileurl; | ||
// Sentry expects frames oldest to newest | ||
// and JS sends them as newest to oldest | ||
frames.reverse(); | ||
stacktrace = {frames: frames}; | ||
fileurl = fileurl || frames[0].filename; | ||
} else if (fileurl) { | ||
@@ -541,3 +561,3 @@ stacktrace = { | ||
send( | ||
arrayMerge({ | ||
objectMerge({ | ||
// sentry.interfaces.Exception | ||
@@ -556,10 +576,10 @@ exception: { | ||
function arrayMerge(arr1, arr2) { | ||
if (!arr2) { | ||
return arr1; | ||
function objectMerge(obj1, obj2) { | ||
if (!obj2) { | ||
return obj1; | ||
} | ||
each(arr2, function(key, value){ | ||
arr1[key] = value; | ||
each(obj2, function(key, value){ | ||
obj1[key] = value; | ||
}); | ||
return arr1; | ||
return obj1; | ||
} | ||
@@ -585,3 +605,3 @@ | ||
data = arrayMerge({ | ||
data = objectMerge({ | ||
project: globalProject, | ||
@@ -595,9 +615,9 @@ logger: globalOptions.logger, | ||
// Merge in the tags and extra separately since arrayMerge doesn't handle a deep merge | ||
data.tags = arrayMerge(globalOptions.tags, data.tags); | ||
data.extra = arrayMerge(globalOptions.extra, data.extra); | ||
// Merge in the tags and extra separately since objectMerge doesn't handle a deep merge | ||
data.tags = objectMerge(globalOptions.tags, data.tags); | ||
data.extra = objectMerge(globalOptions.extra, data.extra); | ||
// If there are no tags/extra, strip the key from the payload alltogther. | ||
if (!data.tags) delete data.tags; | ||
if (!data.extra) delete data.extra; | ||
if (isEmptyObject(data.tags)) delete data.tags; | ||
if (isEmptyObject(data.extra)) delete data.extra; | ||
@@ -618,2 +638,7 @@ if (globalUser) { | ||
// Send along an event_id if not explicitly passed. | ||
// This event_id can be used to reference the error within Sentry itself. | ||
// Set lastEventId after we know the error should actually be sent | ||
lastEventId = data.event_id || (data.event_id = generateUUID4()); | ||
makeRequest(data); | ||
@@ -656,10 +681,17 @@ } | ||
// Be mad. | ||
var sources = [], i = patterns.length; | ||
while (i--) { | ||
sources[i] = isString(patterns[i]) ? | ||
var sources = [], | ||
i = 0, len = patterns.length, | ||
pattern; | ||
for (; i < len; i++) { | ||
pattern = patterns[i]; | ||
if (isString(pattern)) { | ||
// If it's a string, we need to escape it | ||
// Taken from: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions | ||
patterns[i].replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1") : | ||
sources.push(pattern.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1")); | ||
} else if (pattern && pattern.source) { | ||
// If it's a regexp already, we want to extract the source | ||
patterns[i].source; | ||
sources.push(pattern.source); | ||
} | ||
// Intentionally skip other cases | ||
} | ||
@@ -669,4 +701,12 @@ return new RegExp(sources.join('|'), 'i'); | ||
// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523 | ||
function generateUUID4() { | ||
return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) { | ||
var r = Math.random()*16|0, | ||
v = c == 'x' ? r : (r&0x3|0x8); | ||
return v.toString(16); | ||
}); | ||
} | ||
Raven.afterLoad(); | ||
module.exports = Raven; |
@@ -1,2 +0,2 @@ | ||
/*! Raven.js <%= pkg.version %> (<%= gitinfo.local.branch.current.shortSHA %>) | github.com/getsentry/raven-js */ | ||
/*! Raven.js <%= pkg.release %> (<%= gitinfo.local.branch.current.shortSHA %>) | github.com/getsentry/raven-js */ | ||
@@ -7,3 +7,3 @@ /* | ||
* | ||
* Copyright 2013 Matt Robenolt and other contributors | ||
* Copyright <%= grunt.template.today('yyyy') %> Matt Robenolt and other contributors | ||
* Released under the BSD license | ||
@@ -10,0 +10,0 @@ * https://github.com/getsentry/raven-js/blob/master/LICENSE |
;(function(window, undefined){ | ||
'use strict'; |
@@ -5,2 +5,3 @@ function flushRavenState() { | ||
lastCapturedException = undefined; | ||
lastEventId = undefined; | ||
globalServer = undefined; | ||
@@ -38,3 +39,93 @@ globalUser = undefined; | ||
// patched to return a predictable result | ||
function generateUUID4() { | ||
return 'abc123'; | ||
} | ||
describe('TraceKit', function(){ | ||
describe('error notifications', function(){ | ||
var testMessage = "__mocha_ignore__"; | ||
var subscriptionHandler; | ||
// TraceKit waits 2000ms for window.onerror to fire, so give the tests | ||
// some extra time. | ||
this.timeout(3000); | ||
before(function() { | ||
// Prevent the onerror call that's part of our tests from getting to | ||
// mocha's handler, which would treat it as a test failure. | ||
// | ||
// We set this up here and don't ever restore the old handler, because | ||
// we can't do that without clobbering TraceKit's handler, which can only | ||
// be installed once. | ||
var oldOnError = window.onerror; | ||
window.onerror = function(message) { | ||
if (message == testMessage) { | ||
return true; | ||
} | ||
return oldOnError.apply(this, arguments); | ||
}; | ||
}); | ||
afterEach(function() { | ||
if (subscriptionHandler) { | ||
TraceKit.report.unsubscribe(subscriptionHandler); | ||
subscriptionHandler = null; | ||
} | ||
}); | ||
function testErrorNotification(collectWindowErrors, callOnError, numReports, done) { | ||
var extraVal = "foo"; | ||
var numDone = 0; | ||
// TraceKit's collectWindowErrors flag shouldn't affect direct calls | ||
// to TraceKit.report, so we parameterize it for the tests. | ||
TraceKit.collectWindowErrors = collectWindowErrors; | ||
subscriptionHandler = function(stackInfo, extra) { | ||
assert.equal(extra, extraVal); | ||
numDone++; | ||
if (numDone == numReports) { | ||
done(); | ||
} | ||
} | ||
TraceKit.report.subscribe(subscriptionHandler); | ||
// TraceKit.report always throws an exception in order to trigger | ||
// window.onerror so it can gather more stack data. Mocha treats | ||
// uncaught exceptions as errors, so we catch it via assert.throws | ||
// here (and manually call window.onerror later if appropriate). | ||
// | ||
// We test multiple reports because TraceKit has special logic for when | ||
// report() is called a second time before either a timeout elapses or | ||
// window.onerror is called (which is why we always call window.onerror | ||
// only once below, after all calls to report()). | ||
for (var i=0; i < numReports; i++) { | ||
var e = new Error('testing'); | ||
assert.throws(function() { | ||
TraceKit.report(e, extraVal); | ||
}, e); | ||
} | ||
// The call to report should work whether or not window.onerror is | ||
// triggered, so we parameterize it for the tests. We only call it | ||
// once, regardless of numReports, because the case we want to test for | ||
// multiple reports is when window.onerror is *not* called between them. | ||
if (callOnError) { | ||
window.onerror(testMessage); | ||
} | ||
} | ||
Mocha.utils.forEach([false, true], function(collectWindowErrors) { | ||
Mocha.utils.forEach([false, true], function(callOnError) { | ||
Mocha.utils.forEach([1, 2], function(numReports) { | ||
it('it should receive arguments from report() when' + | ||
' collectWindowErrors is ' + collectWindowErrors + | ||
' and callOnError is ' + callOnError + | ||
' and numReports is ' + numReports, function(done) { | ||
testErrorNotification(collectWindowErrors, callOnError, numReports, done); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('globals', function() { | ||
@@ -50,10 +141,2 @@ beforeEach(function() { | ||
it('should not have TraceKit on window', function() { | ||
assert.isUndefined(window.TraceKit); | ||
}); | ||
it('should have a local TK', function() { | ||
assert.isObject(TK); | ||
}); | ||
describe('getHttpData', function() { | ||
@@ -108,2 +191,17 @@ var data = getHttpData(); | ||
describe('isEmptyObject', function() { | ||
it('should work as advertised', function() { | ||
assert.isTrue(isEmptyObject({})); | ||
assert.isFalse(isEmptyObject({foo: 1})); | ||
}); | ||
}); | ||
describe('objectMerge', function() { | ||
it('should work as advertised', function() { | ||
assert.deepEqual(objectMerge({}, {}), {}); | ||
assert.deepEqual(objectMerge({a:1}, {b:2}), {a:1, b:2}); | ||
assert.deepEqual(objectMerge({a:1}), {a:1}); | ||
}); | ||
}); | ||
describe('isSetup', function() { | ||
@@ -411,5 +509,7 @@ it('should return false with no JSON support', function() { | ||
} | ||
]; | ||
], framesFlipped = frames.slice(0); | ||
processException('Error', 'lol', 'http://example.com/override.js', 10, frames, {}); | ||
framesFlipped.reverse(); | ||
processException('Error', 'lol', 'http://example.com/override.js', 10, frames.slice(0), {}); | ||
assert.deepEqual(window.send.lastCall.args, [{ | ||
@@ -421,9 +521,9 @@ exception: { | ||
stacktrace: { | ||
frames: frames | ||
frames: framesFlipped | ||
}, | ||
culprit: 'http://example.com/override.js', | ||
culprit: 'http://example.com/file1.js', | ||
message: 'lol at 10' | ||
}]); | ||
processException('Error', 'lol', '', 10, frames, {}); | ||
processException('Error', 'lol', '', 10, frames.slice(0), {}); | ||
assert.deepEqual(window.send.lastCall.args, [{ | ||
@@ -435,3 +535,3 @@ exception: { | ||
stacktrace: { | ||
frames: frames | ||
frames: framesFlipped | ||
}, | ||
@@ -442,3 +542,3 @@ culprit: 'http://example.com/file1.js', | ||
processException('Error', 'lol', '', 10, frames, {extra: 'awesome'}); | ||
processException('Error', 'lol', '', 10, frames.slice(0), {extra: 'awesome'}); | ||
assert.deepEqual(window.send.lastCall.args, [{ | ||
@@ -450,3 +550,3 @@ exception: { | ||
stacktrace: { | ||
frames: frames | ||
frames: framesFlipped | ||
}, | ||
@@ -538,3 +638,3 @@ culprit: 'http://example.com/file1.js', | ||
globalProject = 2; | ||
globalProject = '2'; | ||
globalOptions = { | ||
@@ -547,3 +647,3 @@ logger: 'javascript', | ||
assert.deepEqual(window.makeRequest.lastCall.args[0], { | ||
project: 2, | ||
project: '2', | ||
logger: 'javascript', | ||
@@ -558,2 +658,3 @@ site: 'THE BEST', | ||
}, | ||
event_id: 'abc123', | ||
foo: 'bar' | ||
@@ -571,3 +672,3 @@ }); | ||
globalProject = 2; | ||
globalProject = '2'; | ||
globalOptions = { | ||
@@ -582,3 +683,3 @@ logger: 'javascript', | ||
assert.deepEqual(window.makeRequest.lastCall.args, [{ | ||
project: 2, | ||
project: '2', | ||
logger: 'javascript', | ||
@@ -593,2 +694,3 @@ site: 'THE BEST', | ||
}, | ||
event_id: 'abc123', | ||
user: { | ||
@@ -609,3 +711,3 @@ name: 'Matt' | ||
globalProject = 2; | ||
globalProject = '2'; | ||
globalOptions = { | ||
@@ -620,3 +722,3 @@ logger: 'javascript', | ||
assert.deepEqual(window.makeRequest.lastCall.args, [{ | ||
project: 2, | ||
project: '2', | ||
logger: 'javascript', | ||
@@ -631,2 +733,3 @@ site: 'THE BEST', | ||
}, | ||
event_id: 'abc123', | ||
tags: {tag1: 'value1', tag2: 'value2'} | ||
@@ -644,3 +747,3 @@ }]); | ||
globalProject = 2; | ||
globalProject = '2'; | ||
globalOptions = { | ||
@@ -655,3 +758,3 @@ logger: 'javascript', | ||
assert.deepEqual(window.makeRequest.lastCall.args, [{ | ||
project: 2, | ||
project: '2', | ||
logger: 'javascript', | ||
@@ -666,2 +769,3 @@ site: 'THE BEST', | ||
}, | ||
event_id: 'abc123', | ||
extra: {key1: 'value1', key2: 'value2'} | ||
@@ -688,5 +792,39 @@ }]); | ||
assert.deepEqual(window.makeRequest.lastCall.args, [{ | ||
lol: 'ibrokeit' | ||
lol: 'ibrokeit', | ||
event_id: 'abc123', | ||
}]); | ||
}); | ||
it('should strip empty tags/extra', function() { | ||
this.sinon.stub(window, 'isSetup').returns(true); | ||
this.sinon.stub(window, 'makeRequest'); | ||
this.sinon.stub(window, 'getHttpData').returns({ | ||
url: 'http://localhost/?a=b', | ||
headers: {'User-Agent': 'lolbrowser'} | ||
}); | ||
globalOptions = { | ||
projectId: 2, | ||
logger: 'javascript', | ||
site: 'THE BEST', | ||
tags: {}, | ||
extra: {} | ||
}; | ||
send({foo: 'bar', tags: {}, extra: {}}); | ||
assert.deepEqual(window.makeRequest.lastCall.args[0], { | ||
project: '2', | ||
logger: 'javascript', | ||
site: 'THE BEST', | ||
platform: 'javascript', | ||
request: { | ||
url: 'http://localhost/?a=b', | ||
headers: { | ||
'User-Agent': 'lolbrowser' | ||
} | ||
}, | ||
event_id: 'abc123', | ||
foo: 'bar' | ||
}); | ||
}); | ||
}); | ||
@@ -766,3 +904,3 @@ | ||
assert.deepEqual(window.makeRequest.lastCall.args, [{ | ||
project: 2, | ||
project: '2', | ||
logger: 'javascript', | ||
@@ -850,2 +988,14 @@ platform: 'javascript', | ||
}); | ||
it('should not process empty or undefined variables', function() { | ||
assert.equal(joinRegExp([ | ||
'a', 'b', null, undefined | ||
]).source, 'a|b'); | ||
}); | ||
it('should skip entries that are not strings or regular expressions in the passed array of patterns', function() { | ||
assert.equal(joinRegExp([ | ||
'a', 'b', null, 'a.b', undefined, true, /d/, 123, {}, /[0-9]/, [] | ||
]).source, 'a|b|a\\.b|d|[0-9]'); | ||
}); | ||
}); | ||
@@ -873,3 +1023,3 @@ }); | ||
this.sinon.stub(window, 'isSetup').returns(false); | ||
this.sinon.stub(TK.report, 'subscribe'); | ||
this.sinon.stub(TraceKit.report, 'subscribe'); | ||
@@ -883,6 +1033,6 @@ Raven.afterLoad(); | ||
assert.equal(globalOptions.some, 'config'); | ||
assert.equal(globalProject, 2); | ||
assert.equal(globalProject, '2'); | ||
assert.isTrue(window.isSetup.calledOnce); | ||
assert.isFalse(TK.report.subscribe.calledOnce); | ||
assert.isFalse(TraceKit.report.subscribe.calledOnce); | ||
@@ -901,3 +1051,4 @@ delete window.RavenConfig; | ||
assert.equal(globalOptions.foo, 'bar'); | ||
assert.equal(globalProject, 2); | ||
assert.equal(globalProject, '2'); | ||
assert.isTrue(isSetup()); | ||
}); | ||
@@ -911,3 +1062,4 @@ | ||
assert.isTrue(globalOptions.ignoreErrors.test('Script error.'), 'it should install "Script error." by default'); | ||
assert.equal(globalProject, 2); | ||
assert.equal(globalProject, '2'); | ||
assert.isTrue(isSetup()); | ||
}); | ||
@@ -919,5 +1071,15 @@ | ||
assert.equal(globalServer, '//example.com/sentry/api/2/store/'); | ||
assert.equal(globalProject, 2); | ||
assert.equal(globalProject, '2'); | ||
assert.isTrue(isSetup()); | ||
}); | ||
it('should noop a falsey dsn', function() { | ||
Raven.config(''); | ||
assert.isFalse(isSetup()); | ||
}); | ||
it('should return Raven for a falsey dsn', function() { | ||
assert.equal(Raven.config(''), Raven); | ||
}); | ||
describe('whitelistUrls', function() { | ||
@@ -955,3 +1117,3 @@ it('should be false if none are passed', function() { | ||
Raven.config(SENTRY_DSN); | ||
assert.isTrue(TK.collectWindowErrors); | ||
assert.isTrue(TraceKit.collectWindowErrors); | ||
}); | ||
@@ -964,3 +1126,3 @@ | ||
assert.isTrue(TK.collectWindowErrors); | ||
assert.isTrue(TraceKit.collectWindowErrors); | ||
}); | ||
@@ -973,3 +1135,3 @@ | ||
assert.isFalse(TK.collectWindowErrors); | ||
assert.isFalse(TraceKit.collectWindowErrors); | ||
}); | ||
@@ -982,6 +1144,6 @@ }); | ||
this.sinon.stub(window, 'isSetup').returns(false); | ||
this.sinon.stub(TK.report, 'subscribe'); | ||
this.sinon.stub(TraceKit.report, 'subscribe'); | ||
Raven.install(); | ||
assert.isTrue(window.isSetup.calledOnce); | ||
assert.isFalse(TK.report.subscribe.calledOnce); | ||
assert.isFalse(TraceKit.report.subscribe.calledOnce); | ||
}); | ||
@@ -991,6 +1153,6 @@ | ||
this.sinon.stub(window, 'isSetup').returns(true); | ||
this.sinon.stub(TK.report, 'subscribe'); | ||
this.sinon.stub(TraceKit.report, 'subscribe'); | ||
assert.equal(Raven, Raven.install()); | ||
assert.isTrue(TK.report.subscribe.calledOnce); | ||
assert.equal(TK.report.subscribe.lastCall.args[0], handleStackInfo); | ||
assert.isTrue(TraceKit.report.subscribe.calledOnce); | ||
assert.equal(TraceKit.report.subscribe.lastCall.args[0], handleStackInfo); | ||
}); | ||
@@ -1024,3 +1186,3 @@ }); | ||
it('should return the result of a wrapped function', function() { | ||
var func = function() { return 'foo' }; | ||
var func = function() { return 'foo'; }; | ||
var wrapped = Raven.wrap(func); | ||
@@ -1048,2 +1210,12 @@ assert.equal(wrapped(), 'foo'); | ||
it('should not wrap function arguments', function() { | ||
var spy = this.sinon.spy(); | ||
var wrapped = Raven.wrap({ deep: false }, function(f) { | ||
assert.isUndefined(f.__raven__); | ||
f(); | ||
}); | ||
wrapped(spy); | ||
assert.isTrue(spy.calledOnce); | ||
}); | ||
it('should maintain the correct scope', function() { | ||
@@ -1137,7 +1309,6 @@ var foo = {}; | ||
describe('.uninstall', function() { | ||
it('should unsubscribe from TraceKit', function() { | ||
this.sinon.stub(TK.report, 'unsubscribe'); | ||
it('should uninstall from TraceKit', function() { | ||
this.sinon.stub(TraceKit.report, 'uninstall'); | ||
Raven.uninstall(); | ||
assert.isTrue(TK.report.unsubscribe.calledOnce); | ||
assert.equal(TK.report.unsubscribe.lastCall.args[0], handleStackInfo); | ||
assert.isTrue(TraceKit.report.uninstall.calledOnce); | ||
}); | ||
@@ -1179,11 +1350,17 @@ }); | ||
}); | ||
it('should tag lastEventId #integration', function() { | ||
setupRaven(); | ||
Raven.captureMessage('lol'); | ||
assert.equal(Raven.lastEventId(), 'abc123'); | ||
}); | ||
}); | ||
describe('.captureException', function() { | ||
it('should call TK.report', function() { | ||
it('should call TraceKit.report', function() { | ||
var error = new Error('crap'); | ||
this.sinon.stub(TK, 'report'); | ||
this.sinon.stub(TraceKit, 'report'); | ||
Raven.captureException(error, {foo: 'bar'}); | ||
assert.isTrue(TK.report.calledOnce); | ||
assert.deepEqual(TK.report.lastCall.args, [error, {foo: 'bar'}]); | ||
assert.isTrue(TraceKit.report.calledOnce); | ||
assert.deepEqual(TraceKit.report.lastCall.args, [error, {foo: 'bar'}]); | ||
}); | ||
@@ -1193,3 +1370,3 @@ | ||
var error = new Error('crap'); | ||
this.sinon.stub(TK, 'report'); | ||
this.sinon.stub(TraceKit, 'report'); | ||
Raven.captureException(error); | ||
@@ -1201,6 +1378,6 @@ assert.equal(Raven.lastException(), error); | ||
var error = new Error('crap'); | ||
this.sinon.stub(TK, 'report').throws(error); | ||
this.sinon.stub(TraceKit, 'report').throws(error); | ||
// this would raise if the errors didn't match | ||
Raven.captureException(error, {foo: 'bar'}); | ||
assert.isTrue(TK.report.calledOnce); | ||
assert.isTrue(TraceKit.report.calledOnce); | ||
}); | ||
@@ -1210,3 +1387,3 @@ | ||
var error = new Error('crap1'); | ||
this.sinon.stub(TK, 'report').throws(error); | ||
this.sinon.stub(TraceKit, 'report').throws(error); | ||
try { | ||
@@ -1223,8 +1400,8 @@ Raven.captureException(new Error('crap2')); | ||
this.sinon.stub(Raven, 'captureMessage'); | ||
this.sinon.stub(TK, 'report'); | ||
this.sinon.stub(TraceKit, 'report'); | ||
Raven.captureException('derp'); | ||
assert.equal(Raven.captureMessage.lastCall.args[0], 'derp'); | ||
assert.isFalse(TK.report.called); | ||
assert.isFalse(TraceKit.report.called); | ||
}); | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No contributors or author data
MaintenancePackage does not specify a list of contributors or an author in package.json.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
256522
0
42
4796
14
3
- Removedtracekit@0.1.0
- Removedtracekit@0.1.0(transitive)