Comparing version 1.1.11 to 1.1.17
{ | ||
"name": "raven-js", | ||
"version": "1.1.11", | ||
"version": "1.1.17", | ||
"dependencies": {}, | ||
"main": "dist/raven.js" | ||
"main": "dist/raven.js", | ||
"ignore": {} | ||
} |
@@ -1,2 +0,2 @@ | ||
/*! Raven.js 1.1.11 (11645a0) | github.com/getsentry/raven-js */ | ||
/*! Raven.js 1.1.17 (aa35178) | github.com/getsentry/raven-js */ | ||
@@ -7,3 +7,3 @@ /* | ||
* | ||
* Copyright 2014 Matt Robenolt and other contributors | ||
* Copyright 2015 Matt Robenolt and other contributors | ||
* Released under the BSD license | ||
@@ -274,3 +274,2 @@ * https://github.com/getsentry/raven-js/blob/master/LICENSE | ||
* Syntax: | ||
* s = TraceKit.computeStackTrace.ofCaller([depth]) | ||
* s = TraceKit.computeStackTrace(exception) // consider using TraceKit.report instead (see below) | ||
@@ -323,15 +322,2 @@ * Returns: | ||
* | ||
* Tracing example: | ||
* function trace(message) { | ||
* var stackInfo = TraceKit.computeStackTrace.ofCaller(); | ||
* var data = message + "\n"; | ||
* for(var i in stackInfo.stack) { | ||
* var item = stackInfo.stack[i]; | ||
* data += (item.func || '[anonymous]') + "() in " + item.url + ":" + (item.line || '0') + "\n"; | ||
* } | ||
* if (window.console) | ||
* console.info(data); | ||
* else | ||
* alert(data); | ||
* } | ||
*/ | ||
@@ -651,4 +637,4 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() { | ||
var chrome = /^\s*at (?:((?:\[object object\])?\S+(?: \[as \S+\])?) )?\(?((?:file|https?):.*?):(\d+)(?::(\d+))?\)?\s*$/i, | ||
gecko = /^\s*(\S*)(?:\((.*?)\))?@((?:file|https?).*?):(\d+)(?::(\d+))?\s*$/i, | ||
var chrome = /^\s*at (.*?) ?\(?((?:file|https?|chrome-extension):.*?):(\d+)(?::(\d+))?\)?\s*$/i, | ||
gecko = /^\s*(.*?)(?:\((.*?)\))?@((?:file|https?|chrome).*?):(\d+)(?::(\d+))?\s*$/i, | ||
lines = ex.stack.split('\n'), | ||
@@ -1070,20 +1056,6 @@ stack = [], | ||
/** | ||
* Logs a stacktrace starting from the previous call and working down. | ||
* @param {(number|string)=} depth How many frames deep to trace. | ||
* @return {Object.<string, *>} Stack trace information. | ||
*/ | ||
function computeStackTraceOfCaller(depth) { | ||
depth = (depth == null ? 0 : +depth) + 1; // "+ 1" because "ofCaller" should drop one frame | ||
try { | ||
throw new Error(); | ||
} catch (ex) { | ||
return computeStackTrace(ex, depth + 1); | ||
} | ||
} | ||
computeStackTrace.augmentStackTraceWithInitialElement = augmentStackTraceWithInitialElement; | ||
computeStackTrace.computeStackTraceFromStackProp = computeStackTraceFromStackProp; | ||
computeStackTrace.guessFunctionName = guessFunctionName; | ||
computeStackTrace.gatherContext = gatherContext; | ||
computeStackTrace.ofCaller = computeStackTraceOfCaller; | ||
@@ -1099,3 +1071,3 @@ return computeStackTrace; | ||
var _Raven = window.Raven, | ||
hasJSON = !!(window.JSON && window.JSON.stringify), | ||
hasJSON = !!(typeof JSON === 'object' && JSON.stringify), | ||
lastCapturedException, | ||
@@ -1115,5 +1087,11 @@ lastEventId, | ||
tags: {}, | ||
maxMessageLength: 100, | ||
extra: {} | ||
}; | ||
}, | ||
authQueryString, | ||
isRavenInstalled = false, | ||
objectPrototype = Object.prototype, | ||
startTime = now(); | ||
/* | ||
@@ -1125,21 +1103,7 @@ * The core Raven singleton | ||
var Raven = { | ||
VERSION: '1.1.11', | ||
VERSION: '1.1.17', | ||
// Expose TraceKit to the Raven namespace | ||
TraceKit: TraceKit, | ||
debug: true, | ||
/* | ||
* Allow Raven to be configured as soon as it is loaded | ||
* It uses a global RavenConfig = {dsn: '...', config: {}} | ||
* | ||
* @return undefined | ||
*/ | ||
afterLoad: function() { | ||
var globalConfig = window.RavenConfig; | ||
if (globalConfig) { | ||
this.config(globalConfig.dsn, globalConfig.config).install(); | ||
} | ||
}, | ||
/* | ||
* Allow multiple versions of Raven to be installed. | ||
@@ -1163,2 +1127,6 @@ * Strip Raven from the global context and returns the instance. | ||
config: function(dsn, options) { | ||
if (globalServer) { | ||
logDebug('error', 'Error: Raven has already been configured'); | ||
return Raven; | ||
} | ||
if (!dsn) return Raven; | ||
@@ -1179,4 +1147,4 @@ | ||
// this is the result of a script being pulled in from an external domain and CORS. | ||
globalOptions.ignoreErrors.push('Script error.'); | ||
globalOptions.ignoreErrors.push('Script error'); | ||
globalOptions.ignoreErrors.push(/^Script error\.?$/); | ||
globalOptions.ignoreErrors.push(/^Javascript error: Script error\.? on line 0$/); | ||
@@ -1211,2 +1179,4 @@ // join regexp rules into one big rule | ||
setAuthQueryString(); | ||
// return for chaining | ||
@@ -1225,4 +1195,5 @@ return Raven; | ||
install: function() { | ||
if (isSetup()) { | ||
if (isSetup() && !isRavenInstalled) { | ||
TraceKit.report.subscribe(handleStackInfo); | ||
isRavenInstalled = true; | ||
} | ||
@@ -1301,3 +1272,3 @@ | ||
for (var property in func) { | ||
if (func.hasOwnProperty(property)) { | ||
if (hasKey(func, property)) { | ||
wrapped[property] = func[property]; | ||
@@ -1310,2 +1281,3 @@ } | ||
wrapped.__raven__ = true; | ||
wrapped.__inner__ = func; | ||
@@ -1322,2 +1294,3 @@ return wrapped; | ||
TraceKit.report.uninstall(); | ||
isRavenInstalled = false; | ||
@@ -1335,4 +1308,4 @@ return Raven; | ||
captureException: function(ex, options) { | ||
// If a string is passed through, recall as a message | ||
if (isString(ex)) return Raven.captureMessage(ex, options); | ||
// If not an Error is passed through, recall as a message instead | ||
if (!isError(ex)) return Raven.captureMessage(ex, options); | ||
@@ -1366,6 +1339,13 @@ // Store the raw exception object for potential debugging and introspection | ||
captureMessage: function(msg, options) { | ||
// config() automagically converts ignoreErrors from a list to a RegExp so we need to test for an | ||
// early call; we'll error on the side of logging anything called before configuration since it's | ||
// probably something you should see: | ||
if (!!globalOptions.ignoreErrors.test && globalOptions.ignoreErrors.test(msg)) { | ||
return; | ||
} | ||
// Fire away! | ||
send( | ||
objectMerge({ | ||
message: msg | ||
message: msg + '' // Make sure it's actually a string | ||
}, options) | ||
@@ -1383,9 +1363,45 @@ ); | ||
*/ | ||
setUser: function(user) { | ||
globalUser = user; | ||
setUserContext: function(user) { | ||
globalUser = user; | ||
return Raven; | ||
return Raven; | ||
}, | ||
/* | ||
* Set extra attributes to be sent along with the payload. | ||
* | ||
* @param {object} extra An object representing extra data [optional] | ||
* @return {Raven} | ||
*/ | ||
setExtraContext: function(extra) { | ||
globalOptions.extra = extra || {}; | ||
return Raven; | ||
}, | ||
/* | ||
* Set tags to be sent along with the payload. | ||
* | ||
* @param {object} tags An object representing tags [optional] | ||
* @return {Raven} | ||
*/ | ||
setTagsContext: function(tags) { | ||
globalOptions.tags = tags || {}; | ||
return Raven; | ||
}, | ||
/* | ||
* Set release version of application | ||
* | ||
* @param {string} release Typically something like a git SHA to identify version | ||
* @return {Raven} | ||
*/ | ||
setReleaseContext: function(release) { | ||
globalOptions.release = release; | ||
return Raven; | ||
}, | ||
/* | ||
* Get the latest raw exception that was captured by Raven. | ||
@@ -1406,5 +1422,16 @@ * | ||
return lastEventId; | ||
}, | ||
/* | ||
* Determine if Raven is setup and ready to go. | ||
* | ||
* @return {boolean} | ||
*/ | ||
isSetup: function() { | ||
return isSetup(); | ||
} | ||
}; | ||
Raven.setUser = Raven.setUserContext; // To be deprecated | ||
function triggerEvent(eventType, options) { | ||
@@ -1425,3 +1452,3 @@ var event, key; | ||
for (key in options) if (options.hasOwnProperty(key)) { | ||
for (key in options) if (hasKey(options, key)) { | ||
event[key] = options[key]; | ||
@@ -1482,2 +1509,6 @@ } | ||
function isObject(what) { | ||
return typeof what === 'object' && what !== null; | ||
} | ||
function isEmptyObject(what) { | ||
@@ -1488,2 +1519,10 @@ for (var k in what) return false; | ||
// Sorta yanked from https://github.com/joyent/node/blob/aa3b4b4/lib/util.js#L560 | ||
// with some tiny modifications | ||
function isError(what) { | ||
return isObject(what) && | ||
objectPrototype.toString.call(what) === '[object Error]' || | ||
what instanceof Error; | ||
} | ||
/** | ||
@@ -1497,3 +1536,3 @@ * hasKey, a better form of hasOwnProperty | ||
function hasKey(object, key) { | ||
return Object.prototype.hasOwnProperty.call(object, key); | ||
return objectPrototype.hasOwnProperty.call(object, key); | ||
} | ||
@@ -1506,3 +1545,3 @@ | ||
for (i in obj) { | ||
if (obj.hasOwnProperty(i)) { | ||
if (hasKey(obj, i)) { | ||
callback.call(null, i, obj[i]); | ||
@@ -1521,19 +1560,11 @@ } | ||
var cachedAuth; | ||
function getAuthQueryString() { | ||
if (cachedAuth) return cachedAuth; | ||
function setAuthQueryString() { | ||
authQueryString = | ||
'?sentry_version=4' + | ||
'&sentry_client=raven-js/' + Raven.VERSION + | ||
'&sentry_key=' + globalKey; | ||
} | ||
var qs = [ | ||
'sentry_version=4', | ||
'sentry_client=raven-js/' + Raven.VERSION | ||
]; | ||
if (globalKey) { | ||
qs.push('sentry_key=' + globalKey); | ||
} | ||
cachedAuth = '?' + qs.join('&'); | ||
return cachedAuth; | ||
} | ||
function handleStackInfo(stackInfo, options) { | ||
@@ -1589,3 +1620,3 @@ var frames = []; | ||
// finally, we do a last ditch effort and check for raven.min.js | ||
/raven\.(min\.)js$/.test(normalized.filename) | ||
/raven\.(min\.)?js$/.test(normalized.filename) | ||
); | ||
@@ -1638,2 +1669,6 @@ | ||
// In some instances message is not actually a string, no idea why, | ||
// so we want to always coerce it to one. | ||
message += ''; | ||
// Sometimes an exception is getting logged in Sentry as | ||
@@ -1644,3 +1679,3 @@ // <no message value> | ||
// At this point, if the message is falsey, we bail since it's useless | ||
if (!message) return; | ||
if (type === 'Error' && !message) return; | ||
@@ -1659,3 +1694,4 @@ if (globalOptions.ignoreErrors.test(message)) return; | ||
filename: fileurl, | ||
lineno: lineno | ||
lineno: lineno, | ||
in_app: true | ||
}] | ||
@@ -1665,2 +1701,5 @@ }; | ||
// Truncate the message to a max of characters | ||
message = truncate(message, globalOptions.maxMessageLength); | ||
if (globalOptions.ignoreUrls && globalOptions.ignoreUrls.test(fileurl)) return; | ||
@@ -1697,2 +1736,10 @@ if (globalOptions.whitelistUrls && !globalOptions.whitelistUrls.test(fileurl)) return; | ||
function truncate(str, max) { | ||
return str.length <= max ? str : str.substr(0, max) + '\u2026'; | ||
} | ||
function now() { | ||
return +new Date(); | ||
} | ||
function getHttpData() { | ||
@@ -1719,3 +1766,2 @@ var http = { | ||
logger: globalOptions.logger, | ||
site: globalOptions.site, | ||
platform: 'javascript', | ||
@@ -1727,8 +1773,12 @@ // sentry.interfaces.Http | ||
// 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); | ||
data.tags = objectMerge(objectMerge({}, globalOptions.tags), data.tags); | ||
data.extra = objectMerge(objectMerge({}, globalOptions.extra), data.extra); | ||
// Send along our own collected metadata with extra | ||
data.extra = objectMerge({ | ||
'session:duration': now() - startTime, | ||
}, data.extra); | ||
// If there are no tags/extra, strip the key from the payload alltogther. | ||
if (isEmptyObject(data.tags)) delete data.tags; | ||
if (isEmptyObject(data.extra)) delete data.extra; | ||
@@ -1740,2 +1790,5 @@ if (globalUser) { | ||
// Include the release iff it's defined in globalOptions | ||
if (globalOptions.release) data.release = globalOptions.release; | ||
if (isFunction(globalOptions.dataCallback)) { | ||
@@ -1753,3 +1806,3 @@ data = globalOptions.dataCallback(data); | ||
// Set lastEventId after we know the error should actually be sent | ||
lastEventId = data.event_id || (data.event_id = generateUUID4()); | ||
lastEventId = data.event_id || (data.event_id = uuid4()); | ||
@@ -1762,4 +1815,5 @@ makeRequest(data); | ||
var img = new Image(), | ||
src = globalServer + getAuthQueryString() + '&sentry_data=' + encodeURIComponent(JSON.stringify(data)); | ||
src = globalServer + authQueryString + '&sentry_data=' + encodeURIComponent(JSON.stringify(data)); | ||
img.crossOrigin = 'anonymous'; | ||
img.onload = function success() { | ||
@@ -1783,5 +1837,3 @@ triggerEvent('success', { | ||
if (!globalServer) { | ||
if (window.console && console.error) { | ||
console.error("Error: Raven has not been configured."); | ||
} | ||
logDebug('error', 'Error: Raven has not been configured.'); | ||
return false; | ||
@@ -1815,3 +1867,3 @@ } | ||
// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523 | ||
function generateUUID4() { | ||
function uuid4() { | ||
return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) { | ||
@@ -1824,12 +1876,35 @@ var r = Math.random()*16|0, | ||
Raven.afterLoad(); | ||
function logDebug(level, message) { | ||
if (window.console && console[level] && Raven.debug) { | ||
console[level](message); | ||
} | ||
} | ||
function afterLoad() { | ||
// Attempt to initialize Raven on load | ||
var RavenConfig = window.RavenConfig; | ||
if (RavenConfig) { | ||
Raven.config(RavenConfig.dsn, RavenConfig.config).install(); | ||
} | ||
} | ||
afterLoad(); | ||
// Expose Raven to the world | ||
window.Raven = Raven; | ||
// AMD | ||
if (typeof define === 'function' && define.amd) { | ||
define('raven', [], function() { return Raven; }); | ||
// AMD | ||
window.Raven = Raven; | ||
define('raven', [], function() { | ||
return Raven; | ||
}); | ||
} else if (typeof module === 'object') { | ||
// browserify | ||
module.exports = Raven; | ||
} else if (typeof exports === 'object') { | ||
// CommonJS | ||
exports = Raven; | ||
} else { | ||
// Everything else | ||
window.Raven = Raven; | ||
} | ||
})(window); |
@@ -1,3 +0,3 @@ | ||
/*! 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); | ||
/*! Raven.js 1.1.17 (aa35178) | 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)l(b,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=V.exec(a),c={},e=7;try{for(;e--;)c[U[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){return"object"==typeof a&&null!==a}function j(a){for(var b in a)return!1;return!0}function k(a){return i(a)&&"[object Error]"===R.toString.call(a)||a instanceof Error}function l(a,b){return R.hasOwnProperty.call(a,b)}function m(a,b){var c,d;if(f(a.length))for(c in a)l(a,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 n(){M="?sentry_version=4&sentry_client=raven-js/"+T.VERSION+"&sentry_key="+K}function o(a,b){var d=[];a.stack&&a.stack.length&&m(a.stack,function(a,b){var c=p(b);c&&d.push(c)}),c("handle",{stackInfo:a,options:b}),r(a.name,a.message,a.url,a.lineno,d,b)}function p(a){if(a.url){var b,c={filename:a.url,lineno:a.line,colno:a.column,"function":a.func||"?"},d=q(a);if(d){var e=["pre_context","context_line","post_context"];for(b=3;b--;)c[e[b]]=d[b]}return c.in_app=!(!P.includePaths.test(c.filename)||/(Raven|TraceKit)\./.test(c["function"])||/raven\.(min\.)?js$/.test(c.filename)),c}}function q(a){if(a.context&&P.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 r(a,b,c,d,e,f){var g,h;b+="",("Error"!==a||b)&&(P.ignoreErrors.test(b)||(e&&e.length?(c=e[0].filename||c,e.reverse(),g={frames:e}):c&&(g={frames:[{filename:c,lineno:d,in_app:!0}]}),b=t(b,P.maxMessageLength),P.ignoreUrls&&P.ignoreUrls.test(c)||(!P.whitelistUrls||P.whitelistUrls.test(c))&&(h=d?b+" at "+d:b,w(s({exception:{type:a,value:b},stacktrace:g,culprit:c,message:h},f)))))}function s(a,b){return b?(m(b,function(b,c){a[b]=c}),a):a}function t(a,b){return a.length<=b?a:a.substr(0,b)+"…"}function u(){return+new Date}function v(){var a={url:document.location.href,headers:{"User-Agent":navigator.userAgent}};return document.referrer&&(a.headers.Referer=document.referrer),a}function w(a){y()&&(a=s({project:L,logger:P.logger,platform:"javascript",request:v()},a),a.tags=s(s({},P.tags),a.tags),a.extra=s(s({},P.extra),a.extra),a.extra=s({"session:duration":u()-S},a.extra),j(a.tags)&&delete a.tags,J&&(a.user=J),P.release&&(a.release=P.release),g(P.dataCallback)&&(a=P.dataCallback(a)),(!g(P.shouldSendCallback)||P.shouldSendCallback(a))&&(H=a.event_id||(a.event_id=A()),x(a)))}function x(a){var b=new Image,d=I+M+"&sentry_data="+encodeURIComponent(JSON.stringify(a));b.crossOrigin="anonymous",b.onload=function(){c("success",{data:a,src:d})},b.onerror=b.onabort=function(){c("failure",{data:a,src:d})},b.src=d}function y(){return O?I?!0:(B("error","Error: Raven has not been configured."),!1):!1}function z(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 A(){return"xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx".replace(/[xy]/g,function(a){var b=16*Math.random()|0,c="x"==a?b:3&b|8;return c.toString(16)})}function B(b,c){a.console&&console[b]&&T.debug&&console[b](c)}function C(){var b=a.RavenConfig;b&&T.config(b.dsn,b.config).install()}var D={remoteFetching:!1,collectWindowErrors:!0,linesOfContext:7},E=[].slice,F="?";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){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||D.collectWindowErrors){for(var d in o)if(l(o,d))try{o[d].apply(null,[a].concat(E.call(arguments,2)))}catch(e){c=e}if(c)throw c}}function g(a,b,c,d,e){var g=null;if(r)D.computeStackTrace.augmentStackTraceWithInitialElement(r,b,c,a),j();else if(e)g=D.computeStackTrace(e),f(g,!0);else{var h={url:b,line:c,column:d};h.func=D.computeStackTrace.guessFunctionName(h.url,h.line),h.context=D.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 j(){var a=r,b=p;p=null,r=null,q=null,f.apply(null,[a,!1].concat(b))}function k(b,c){var d=E.call(arguments,1);if(r){if(q===b)return;j()}var e=D.computeStackTrace(b);if(r=e,q=b,p=d,a.setTimeout(function(){q===b&&j()},e.incomplete?2e3:0),c!==!1)throw b}var m,n,o=[],p=null,q=null,r=null;return k.subscribe=c,k.unsubscribe=d,k.uninstall=e,k}(),D.computeStackTrace=function(){function b(b){if(!D.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(!l(u,a)){var c="";-1!==a.indexOf(document.domain)&&(c=b(a)),u[a]=c?c.split("\n"):[]}return u[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 F;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 F}function e(a,b){var d=c(a);if(!d.length)return null;var e=[],g=Math.floor(D.linesOfContext/2),h=g+D.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 j(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 k(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],k=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<k.length;++o){var p=k[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=j(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=j(d,h[0]))return f;if(d=new RegExp(c),f=j(d,h))return f}return null}function n(a){if(!a.stack)return null;for(var b,c,g=/^\s*at (.*?) ?\(?((?:file|https?|chrome-extension):.*?):(\d+)(?::(\d+))?\)?\s*$/i,h=/^\s*(.*?)(?:\((.*?)\))?@((?:file|https?|chrome).*?):(\d+)(?::(\d+))?\s*$/i,i=a.stack.split("\n"),j=[],l=/^(.*) 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]||F,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]||F,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&&l?j[0].column=k(l[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,k,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)l(r,h)&&!r[h].src&&s.push(r[h]);for(h=2,k=f.length;k>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=j(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=k(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,l=r.caller;l&&!j;l=l.caller)if(l!==s&&l!==D.report){if(e={url:null,func:F,line:null,column:null},l.name?e.func=l.name:(c=g.exec(l.toString()))&&(e.func=c[1]),f=m(l)){e.url=f.url,e.line=f.line,e.func===F&&(e.func=d(e.url,e.line));var n=/ '([^']+)' /.exec(a.message||a.description);n&&(e.column=k(n[1],f.url,f.line))}i[""+l]?j=!0:i[""+l]=!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(t)throw d}try{if(c=n(a))return c}catch(d){if(t)throw d}try{if(c=p(a))return c}catch(d){if(t)throw d}try{if(c=r(a,b+1))return c}catch(d){if(t)throw d}return{}}var t=!1,u={};return s.augmentStackTraceWithInitialElement=q,s.computeStackTraceFromStackProp=n,s.guessFunctionName=d,s.gatherContext=e,s}();var G,H,I,J,K,L,M,N=a.Raven,O=!("object"!=typeof JSON||!JSON.stringify),P={logger:"javascript",ignoreErrors:[],ignoreUrls:[],whitelistUrls:[],includePaths:[],collectWindowErrors:!0,tags:{},maxMessageLength:100,extra:{}},Q=!1,R=Object.prototype,S=u(),T={VERSION:"1.1.17",debug:!0,noConflict:function(){return a.Raven=N,T},config:function(a,b){if(I)return B("error","Error: Raven has already been configured"),T;if(!a)return T;var c=e(a),d=c.path.lastIndexOf("/"),f=c.path.substr(1,d);return b&&m(b,function(a,b){P[a]=b}),P.ignoreErrors.push(/^Script error\.?$/),P.ignoreErrors.push(/^Javascript error: Script error\.? on line 0$/),P.ignoreErrors=z(P.ignoreErrors),P.ignoreUrls=P.ignoreUrls.length?z(P.ignoreUrls):!1,P.whitelistUrls=P.whitelistUrls.length?z(P.whitelistUrls):!1,P.includePaths=z(P.includePaths),K=c.user,L=c.path.substr(d+1),I="//"+c.host+(c.port?":"+c.port:"")+"/"+f+"api/"+L+"/store/",c.protocol&&(I=c.protocol+":"+I),P.fetchContext&&(D.remoteFetching=!0),P.linesOfContext&&(D.linesOfContext=P.linesOfContext),D.collectWindowErrors=!!P.collectWindowErrors,n(),T},install:function(){return y()&&!Q&&(D.report.subscribe(o),Q=!0),T},context:function(a,c,d){return g(a)&&(d=c||[],c=a,a=b),T.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?T.wrap(a,arguments[d]):arguments[d];try{return c.apply(this,b)}catch(f){throw T.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)l(c,e)&&(d[e]=c[e]);return d.__raven__=!0,d.__inner__=c,d},uninstall:function(){return D.report.uninstall(),Q=!1,T},captureException:function(a,b){if(!k(a))return T.captureMessage(a,b);G=a;try{D.report(a,b)}catch(c){if(a!==c)throw c}return T},captureMessage:function(a,b){return P.ignoreErrors.test&&P.ignoreErrors.test(a)?void 0:(w(s({message:a+""},b)),T)},setUserContext:function(a){return J=a,T},setExtraContext:function(a){return P.extra=a||{},T},setTagsContext:function(a){return P.tags=a||{},T},setReleaseContext:function(a){return P.release=a,T},lastException:function(){return G},lastEventId:function(){return H},isSetup:function(){return y()}};T.setUser=T.setUserContext;var U="source protocol user pass host port path".split(" "),V=/^(?:(\w+):)?\/\/(\w+)(:\w+)?@([\w\.-]+)(?::(\d+))?(\/.*)/;d.prototype=new Error,d.prototype.constructor=d,C(),"function"==typeof define&&define.amd?(a.Raven=T,define("raven",[],function(){return T})):"object"==typeof module?module.exports=T:"object"==typeof exports?exports=T:a.Raven=T}(window); | ||
//# sourceMappingURL=raven.min.map |
@@ -54,3 +54,3 @@ module.exports = function(grunt) { | ||
var dest = path.join('build/', key.join(','), '/<%= pkg.name %>.js'); | ||
var dest = path.join('build/', key.join(','), '/raven.js'); | ||
dict[dest] = coreFiles.concat(comb); | ||
@@ -74,3 +74,3 @@ | ||
src: coreFiles.concat(plugins), | ||
dest: 'build/<%= pkg.name %>.js' | ||
dest: 'build/raven.js' | ||
}, | ||
@@ -140,3 +140,9 @@ all: { | ||
bucket: '<%= aws.bucket %>', | ||
access: 'public-read' | ||
access: 'public-read', | ||
// Limit concurrency | ||
maxOperations: 20, | ||
headers: { | ||
// Surrogate-Key header for Fastly to purge by release | ||
'x-amz-meta-surrogate-key': '<%= pkg.release %>' | ||
} | ||
}, | ||
@@ -234,4 +240,7 @@ all: { | ||
// Build tasks | ||
grunt.registerTask('build.core', ['clean', 'gitinfo', 'version', 'concat:core', 'uglify', 'fixSourceMaps']); | ||
grunt.registerTask('build.all', ['clean', 'gitinfo', 'version', 'concat:all', 'uglify', 'fixSourceMaps']); | ||
grunt.registerTask('_prep', ['clean', 'gitinfo', 'version']); | ||
grunt.registerTask('concat.core', ['_prep', 'concat:core']); | ||
grunt.registerTask('concat.all', ['_prep', 'concat:all']); | ||
grunt.registerTask('build.core', ['concat.core', 'uglify', 'fixSourceMaps']); | ||
grunt.registerTask('build.all', ['concat.all', 'uglify', 'fixSourceMaps']); | ||
grunt.registerTask('build', ['build.all']); | ||
@@ -238,0 +247,0 @@ grunt.registerTask('dist', ['build.core', 'copy:dist']); |
{ | ||
"name": "raven-js", | ||
"version": "1.1.11", | ||
"main": "./src/raven.js", | ||
"version": "1.1.17", | ||
"scripts": { | ||
"test": "./node_modules/.bin/grunt test" | ||
"pretest": "npm install", | ||
"test": "grunt test" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git://github.com/defunctzombie/raven-js.git" | ||
"url": "git://github.com/getsentry/raven-js.git" | ||
}, | ||
"main": "dist/raven.js", | ||
"devDependencies": { | ||
@@ -13,0 +14,0 @@ "chai": "~1.8.1", |
@@ -22,3 +22,7 @@ /** | ||
if (originalConsoleLevel) { | ||
originalConsoleLevel.apply(originalConsole, args); | ||
// IE9 doesn't allow calling apply on console functions directly | ||
// See: https://stackoverflow.com/questions/5472938/does-ie9-support-console-log-and-is-it-a-real-function#answer-5473193 | ||
Function.prototype.bind | ||
.call(originalConsoleLevel, originalConsole) | ||
.apply(originalConsole, args); | ||
} | ||
@@ -37,2 +41,2 @@ }; | ||
}(this, Raven, console || {})); | ||
}(window, window.Raven, window.console || {})); |
@@ -75,2 +75,2 @@ /** | ||
}(this, Raven, window.jQuery)); | ||
}(window, window.Raven, window.jQuery)); |
@@ -5,3 +5,3 @@ /** | ||
* Extends support for global error handling for asynchronous browser | ||
* functions. Adopted from Closure Library's errorhandler.js | ||
* functions. Adopted from Closure Library's errorhandler.js. | ||
*/ | ||
@@ -20,4 +20,4 @@ ;(function extendToAsynchronousCallbacks(window, Raven) { | ||
} | ||
// IE < 9 doesn't support .call/.apply on setInterval/etTimeout, but it | ||
// also only supports 2 argument and doesn't care what this" is, so we | ||
// IE < 9 doesn't support .call/.apply on setInterval/setTimeout, but it | ||
// also supports only two arguments and doesn't care what this is, so we | ||
// can just call the original function directly. | ||
@@ -35,2 +35,2 @@ if (originalFn.apply) { | ||
}(this, Raven)); | ||
}(window, window.Raven)); |
@@ -7,8 +7,9 @@ /** | ||
;(function(window, Raven) { | ||
"use strict"; | ||
'use strict'; | ||
if (typeof define === 'function' && define.amd) { | ||
window.define = Raven.wrap(define); | ||
window.require = Raven.wrap(require); | ||
} | ||
}(this, Raven)); | ||
if (typeof define === 'function' && define.amd) { | ||
window.define = Raven.wrap({deep: false}, define); | ||
window.require = Raven.wrap({deep: false}, require); | ||
} | ||
}(window, window.Raven)); |
@@ -1,4 +0,4 @@ | ||
# Raven.js | ||
# Raven.js [![Build Status](https://travis-ci.org/getsentry/raven-js.svg?branch=master)](https://travis-ci.org/getsentry/raven-js) | ||
Raven.js is a tiny standalone JavaScript client for [Sentry](http://www.getsentry.com/). | ||
Raven.js is a tiny standalone JavaScript client for [Sentry](https://www.getsentry.com/). | ||
@@ -10,5 +10,5 @@ **Raven.js v1.1 requires Sentry v6.0 or later.** | ||
* [Download](http://ravenjs.com) | ||
* [Documentation](http://raven-js.readthedocs.org) | ||
* [Documentation](https://raven-js.readthedocs.org) | ||
* [Bug Tracker](https://github.com/getsentry/raven-js/issues) | ||
* [IRC](irc://chat.freenode.net/sentry) (chat.freenode.net, #sentry) | ||
* Follow [@mattrobenolt](https://twitter.com/mattrobenolt) on Twitter for updates |
223
src/raven.js
'use strict'; | ||
var TraceKit = require('../vendor/TraceKit/tracekit'); | ||
// First, check for JSON support | ||
@@ -9,3 +7,3 @@ // If there is no JSON, we no-op the core features of Raven | ||
var _Raven = window.Raven, | ||
hasJSON = !!(window.JSON && window.JSON.stringify), | ||
hasJSON = !!(typeof JSON === 'object' && JSON.stringify), | ||
lastCapturedException, | ||
@@ -25,5 +23,11 @@ lastEventId, | ||
tags: {}, | ||
maxMessageLength: 100, | ||
extra: {} | ||
}; | ||
}, | ||
authQueryString, | ||
isRavenInstalled = false, | ||
objectPrototype = Object.prototype, | ||
startTime = now(); | ||
/* | ||
@@ -35,21 +39,7 @@ * The core Raven singleton | ||
var Raven = { | ||
VERSION: '1.1.11', | ||
VERSION: '<%= pkg.version %>', | ||
// Expose TraceKit to the Raven namespace | ||
TraceKit: TraceKit, | ||
debug: true, | ||
/* | ||
* Allow Raven to be configured as soon as it is loaded | ||
* It uses a global RavenConfig = {dsn: '...', config: {}} | ||
* | ||
* @return undefined | ||
*/ | ||
afterLoad: function() { | ||
var globalConfig = window.RavenConfig; | ||
if (globalConfig) { | ||
this.config(globalConfig.dsn, globalConfig.config).install(); | ||
} | ||
}, | ||
/* | ||
* Allow multiple versions of Raven to be installed. | ||
@@ -73,2 +63,6 @@ * Strip Raven from the global context and returns the instance. | ||
config: function(dsn, options) { | ||
if (globalServer) { | ||
logDebug('error', 'Error: Raven has already been configured'); | ||
return Raven; | ||
} | ||
if (!dsn) return Raven; | ||
@@ -89,4 +83,4 @@ | ||
// this is the result of a script being pulled in from an external domain and CORS. | ||
globalOptions.ignoreErrors.push('Script error.'); | ||
globalOptions.ignoreErrors.push('Script error'); | ||
globalOptions.ignoreErrors.push(/^Script error\.?$/); | ||
globalOptions.ignoreErrors.push(/^Javascript error: Script error\.? on line 0$/); | ||
@@ -121,2 +115,4 @@ // join regexp rules into one big rule | ||
setAuthQueryString(); | ||
// return for chaining | ||
@@ -135,4 +131,5 @@ return Raven; | ||
install: function() { | ||
if (isSetup()) { | ||
if (isSetup() && !isRavenInstalled) { | ||
TraceKit.report.subscribe(handleStackInfo); | ||
isRavenInstalled = true; | ||
} | ||
@@ -211,3 +208,3 @@ | ||
for (var property in func) { | ||
if (func.hasOwnProperty(property)) { | ||
if (hasKey(func, property)) { | ||
wrapped[property] = func[property]; | ||
@@ -220,2 +217,3 @@ } | ||
wrapped.__raven__ = true; | ||
wrapped.__inner__ = func; | ||
@@ -232,2 +230,3 @@ return wrapped; | ||
TraceKit.report.uninstall(); | ||
isRavenInstalled = false; | ||
@@ -245,4 +244,4 @@ return Raven; | ||
captureException: function(ex, options) { | ||
// If a string is passed through, recall as a message | ||
if (isString(ex)) return Raven.captureMessage(ex, options); | ||
// If not an Error is passed through, recall as a message instead | ||
if (!isError(ex)) return Raven.captureMessage(ex, options); | ||
@@ -276,6 +275,13 @@ // Store the raw exception object for potential debugging and introspection | ||
captureMessage: function(msg, options) { | ||
// config() automagically converts ignoreErrors from a list to a RegExp so we need to test for an | ||
// early call; we'll error on the side of logging anything called before configuration since it's | ||
// probably something you should see: | ||
if (!!globalOptions.ignoreErrors.test && globalOptions.ignoreErrors.test(msg)) { | ||
return; | ||
} | ||
// Fire away! | ||
send( | ||
objectMerge({ | ||
message: msg | ||
message: msg + '' // Make sure it's actually a string | ||
}, options) | ||
@@ -293,9 +299,45 @@ ); | ||
*/ | ||
setUser: function(user) { | ||
globalUser = user; | ||
setUserContext: function(user) { | ||
globalUser = user; | ||
return Raven; | ||
return Raven; | ||
}, | ||
/* | ||
* Set extra attributes to be sent along with the payload. | ||
* | ||
* @param {object} extra An object representing extra data [optional] | ||
* @return {Raven} | ||
*/ | ||
setExtraContext: function(extra) { | ||
globalOptions.extra = extra || {}; | ||
return Raven; | ||
}, | ||
/* | ||
* Set tags to be sent along with the payload. | ||
* | ||
* @param {object} tags An object representing tags [optional] | ||
* @return {Raven} | ||
*/ | ||
setTagsContext: function(tags) { | ||
globalOptions.tags = tags || {}; | ||
return Raven; | ||
}, | ||
/* | ||
* Set release version of application | ||
* | ||
* @param {string} release Typically something like a git SHA to identify version | ||
* @return {Raven} | ||
*/ | ||
setReleaseContext: function(release) { | ||
globalOptions.release = release; | ||
return Raven; | ||
}, | ||
/* | ||
* Get the latest raw exception that was captured by Raven. | ||
@@ -316,5 +358,16 @@ * | ||
return lastEventId; | ||
}, | ||
/* | ||
* Determine if Raven is setup and ready to go. | ||
* | ||
* @return {boolean} | ||
*/ | ||
isSetup: function() { | ||
return isSetup(); | ||
} | ||
}; | ||
Raven.setUser = Raven.setUserContext; // To be deprecated | ||
function triggerEvent(eventType, options) { | ||
@@ -335,3 +388,3 @@ var event, key; | ||
for (key in options) if (options.hasOwnProperty(key)) { | ||
for (key in options) if (hasKey(options, key)) { | ||
event[key] = options[key]; | ||
@@ -392,2 +445,6 @@ } | ||
function isObject(what) { | ||
return typeof what === 'object' && what !== null; | ||
} | ||
function isEmptyObject(what) { | ||
@@ -398,2 +455,21 @@ for (var k in what) return false; | ||
// Sorta yanked from https://github.com/joyent/node/blob/aa3b4b4/lib/util.js#L560 | ||
// with some tiny modifications | ||
function isError(what) { | ||
return isObject(what) && | ||
objectPrototype.toString.call(what) === '[object Error]' || | ||
what instanceof Error; | ||
} | ||
/** | ||
* 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 objectPrototype.hasOwnProperty.call(object, key); | ||
} | ||
function each(obj, callback) { | ||
@@ -404,3 +480,3 @@ var i, j; | ||
for (i in obj) { | ||
if (obj.hasOwnProperty(i)) { | ||
if (hasKey(obj, i)) { | ||
callback.call(null, i, obj[i]); | ||
@@ -419,19 +495,11 @@ } | ||
var cachedAuth; | ||
function getAuthQueryString() { | ||
if (cachedAuth) return cachedAuth; | ||
function setAuthQueryString() { | ||
authQueryString = | ||
'?sentry_version=4' + | ||
'&sentry_client=raven-js/' + Raven.VERSION + | ||
'&sentry_key=' + globalKey; | ||
} | ||
var qs = [ | ||
'sentry_version=4', | ||
'sentry_client=raven-js/' + Raven.VERSION | ||
]; | ||
if (globalKey) { | ||
qs.push('sentry_key=' + globalKey); | ||
} | ||
cachedAuth = '?' + qs.join('&'); | ||
return cachedAuth; | ||
} | ||
function handleStackInfo(stackInfo, options) { | ||
@@ -487,3 +555,3 @@ var frames = []; | ||
// finally, we do a last ditch effort and check for raven.min.js | ||
/raven\.(min\.)js$/.test(normalized.filename) | ||
/raven\.(min\.)?js$/.test(normalized.filename) | ||
); | ||
@@ -536,2 +604,6 @@ | ||
// In some instances message is not actually a string, no idea why, | ||
// so we want to always coerce it to one. | ||
message += ''; | ||
// Sometimes an exception is getting logged in Sentry as | ||
@@ -542,3 +614,3 @@ // <no message value> | ||
// At this point, if the message is falsey, we bail since it's useless | ||
if (!message) return; | ||
if (type === 'Error' && !message) return; | ||
@@ -557,3 +629,4 @@ if (globalOptions.ignoreErrors.test(message)) return; | ||
filename: fileurl, | ||
lineno: lineno | ||
lineno: lineno, | ||
in_app: true | ||
}] | ||
@@ -563,2 +636,5 @@ }; | ||
// Truncate the message to a max of characters | ||
message = truncate(message, globalOptions.maxMessageLength); | ||
if (globalOptions.ignoreUrls && globalOptions.ignoreUrls.test(fileurl)) return; | ||
@@ -595,2 +671,10 @@ if (globalOptions.whitelistUrls && !globalOptions.whitelistUrls.test(fileurl)) return; | ||
function truncate(str, max) { | ||
return str.length <= max ? str : str.substr(0, max) + '\u2026'; | ||
} | ||
function now() { | ||
return +new Date(); | ||
} | ||
function getHttpData() { | ||
@@ -617,3 +701,2 @@ var http = { | ||
logger: globalOptions.logger, | ||
site: globalOptions.site, | ||
platform: 'javascript', | ||
@@ -625,8 +708,12 @@ // sentry.interfaces.Http | ||
// 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); | ||
data.tags = objectMerge(objectMerge({}, globalOptions.tags), data.tags); | ||
data.extra = objectMerge(objectMerge({}, globalOptions.extra), data.extra); | ||
// Send along our own collected metadata with extra | ||
data.extra = objectMerge({ | ||
'session:duration': now() - startTime, | ||
}, data.extra); | ||
// If there are no tags/extra, strip the key from the payload alltogther. | ||
if (isEmptyObject(data.tags)) delete data.tags; | ||
if (isEmptyObject(data.extra)) delete data.extra; | ||
@@ -638,2 +725,5 @@ if (globalUser) { | ||
// Include the release iff it's defined in globalOptions | ||
if (globalOptions.release) data.release = globalOptions.release; | ||
if (isFunction(globalOptions.dataCallback)) { | ||
@@ -651,3 +741,3 @@ data = globalOptions.dataCallback(data); | ||
// Set lastEventId after we know the error should actually be sent | ||
lastEventId = data.event_id || (data.event_id = generateUUID4()); | ||
lastEventId = data.event_id || (data.event_id = uuid4()); | ||
@@ -660,4 +750,5 @@ makeRequest(data); | ||
var img = new Image(), | ||
src = globalServer + getAuthQueryString() + '&sentry_data=' + encodeURIComponent(JSON.stringify(data)); | ||
src = globalServer + authQueryString + '&sentry_data=' + encodeURIComponent(JSON.stringify(data)); | ||
img.crossOrigin = 'anonymous'; | ||
img.onload = function success() { | ||
@@ -681,5 +772,3 @@ triggerEvent('success', { | ||
if (!globalServer) { | ||
if (window.console && console.error) { | ||
console.error("Error: Raven has not been configured."); | ||
} | ||
logDebug('error', 'Error: Raven has not been configured.'); | ||
return false; | ||
@@ -713,3 +802,3 @@ } | ||
// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523 | ||
function generateUUID4() { | ||
function uuid4() { | ||
return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) { | ||
@@ -722,3 +811,15 @@ var r = Math.random()*16|0, | ||
Raven.afterLoad(); | ||
module.exports = Raven; | ||
function logDebug(level, message) { | ||
if (window.console && console[level] && Raven.debug) { | ||
console[level](message); | ||
} | ||
} | ||
function afterLoad() { | ||
// Attempt to initialize Raven on load | ||
var RavenConfig = window.RavenConfig; | ||
if (RavenConfig) { | ||
Raven.config(RavenConfig.dsn, RavenConfig.config).install(); | ||
} | ||
} | ||
afterLoad(); |
// Expose Raven to the world | ||
window.Raven = Raven; | ||
// AMD | ||
if (typeof define === 'function' && define.amd) { | ||
define('raven', [], function() { return Raven; }); | ||
// AMD | ||
window.Raven = Raven; | ||
define('raven', [], function() { | ||
return Raven; | ||
}); | ||
} else if (typeof module === 'object') { | ||
// browserify | ||
module.exports = Raven; | ||
} else if (typeof exports === 'object') { | ||
// CommonJS | ||
exports = Raven; | ||
} else { | ||
// Everything else | ||
window.Raven = Raven; | ||
} | ||
})(window); |
function flushRavenState() { | ||
cachedAuth = undefined; | ||
authQueryString = undefined; | ||
hasJSON = !isUndefined(window.JSON); | ||
@@ -11,2 +11,3 @@ lastCapturedException = undefined; | ||
logger: 'javascript', | ||
release: undefined, | ||
ignoreErrors: [], | ||
@@ -17,5 +18,9 @@ ignoreUrls: [], | ||
collectWindowErrors: true, | ||
maxMessageLength: 100, | ||
tags: {}, | ||
extra: {} | ||
}; | ||
}, | ||
startTime = 0 | ||
; | ||
Raven.uninstall(); | ||
@@ -41,7 +46,37 @@ } | ||
// patched to return a predictable result | ||
function generateUUID4() { | ||
function uuid4() { | ||
return 'abc123'; | ||
} | ||
// patched to be predictable | ||
function now() { | ||
return 100; | ||
} | ||
describe('TraceKit', function(){ | ||
describe('stacktrace info', function() { | ||
it('should not remove anonymous functions from the stack', function() { | ||
// mock up an error object with a stack trace that includes both | ||
// named functions and anonymous functions | ||
var stack_str = "" + | ||
" Error: \n" + | ||
" at new <anonymous> (http://example.com/js/test.js:63)\n" + // stack[0] | ||
" at namedFunc0 (http://example.com/js/script.js:10)\n" + // stack[1] | ||
" at http://example.com/js/test.js:65\n" + // stack[2] | ||
" at namedFunc2 (http://example.com/js/script.js:20)\n" + // stack[3] | ||
" at http://example.com/js/test.js:67\n" + // stack[4] | ||
" at namedFunc4 (http://example.com/js/script.js:100001)"; // stack[5] | ||
var mock_err = { stack: stack_str }; | ||
var trace = TraceKit.computeStackTrace.computeStackTraceFromStackProp(mock_err); | ||
// Make sure TraceKit didn't remove the anonymous functions | ||
// from the stack like it used to :) | ||
assert.equal(trace.stack[0].func, 'new <anonymous>'); | ||
assert.equal(trace.stack[1].func, 'namedFunc0'); | ||
assert.equal(trace.stack[2].func, '?'); | ||
assert.equal(trace.stack[3].func, 'namedFunc2'); | ||
assert.equal(trace.stack[4].func, '?'); | ||
assert.equal(trace.stack[5].func, 'namedFunc4'); | ||
}); | ||
}); | ||
describe('error notifications', function(){ | ||
@@ -90,3 +125,3 @@ var testMessage = "__mocha_ignore__"; | ||
} | ||
} | ||
}; | ||
TraceKit.report.subscribe(subscriptionHandler); | ||
@@ -188,6 +223,14 @@ | ||
assert.isFalse(isString(undefined)); | ||
assert.isFalse(isString(function(){})) | ||
assert.isFalse(isString(function(){})); | ||
}); | ||
}); | ||
describe('isObject', function() { | ||
it('should do as advertised', function() { | ||
assert.isTrue(isObject({})); | ||
assert.isTrue(isObject(new Error())) | ||
assert.isFalse(isObject('')); | ||
}); | ||
}); | ||
describe('isEmptyObject', function() { | ||
@@ -200,2 +243,13 @@ it('should work as advertised', function() { | ||
describe('isError', function() { | ||
it('should work as advertised', function() { | ||
assert.isTrue(isError(new Error())); | ||
assert.isTrue(isError(new ReferenceError())); | ||
assert.isTrue(isError(new RavenConfigError())); | ||
assert.isFalse(isError({})); | ||
assert.isFalse(isError('')); | ||
assert.isFalse(isError(true)); | ||
}); | ||
}); | ||
describe('objectMerge', function() { | ||
@@ -209,2 +263,10 @@ it('should work as advertised', function() { | ||
describe('truncate', function() { | ||
it('should work as advertised', function() { | ||
assert.equal(truncate('lolol', 3), 'lol\u2026'); | ||
assert.equal(truncate('lolol', 10), 'lolol'); | ||
assert.equal(truncate('lol', 3), 'lol'); | ||
}); | ||
}); | ||
describe('isSetup', function() { | ||
@@ -217,8 +279,7 @@ it('should return false with no JSON support', function() { | ||
it('should return false when Raven is not configured and write to console.error', function() { | ||
it('should return false when Raven is not configured', function() { | ||
hasJSON = true; // be explicit | ||
globalServer = undefined; | ||
this.sinon.stub(console, 'error'); | ||
this.sinon.stub(window, 'logDebug'); | ||
assert.isFalse(isSetup()); | ||
assert.isTrue(console.error.calledOnce); | ||
}); | ||
@@ -232,15 +293,29 @@ | ||
describe('getAuthQueryString', function() { | ||
it('should return a properly formatted string and cache it', function() { | ||
var expected = '?sentry_version=4&sentry_client=raven-js/<%= pkg.version %>&sentry_key=abc'; | ||
assert.strictEqual(getAuthQueryString(), expected); | ||
assert.strictEqual(cachedAuth, expected); | ||
describe('logDebug', function() { | ||
var level = 'error', | ||
message = 'foobar'; | ||
it('should not write to console when Raven.debug is false', function() { | ||
Raven.debug = false; | ||
this.sinon.stub(console, level); | ||
logDebug(level, message); | ||
assert.isFalse(console[level].called); | ||
}); | ||
it('should return cached value when it exists', function() { | ||
cachedAuth = 'lol'; | ||
assert.strictEqual(getAuthQueryString(), 'lol'); | ||
it('should write to console when Raven.debug is true', function() { | ||
Raven.debug = true; | ||
this.sinon.stub(console, level); | ||
logDebug(level, message); | ||
assert.isTrue(console[level].calledOnce); | ||
}); | ||
}); | ||
describe('setAuthQueryString', function() { | ||
it('should return a properly formatted string and cache it', function() { | ||
var expected = '?sentry_version=4&sentry_client=raven-js/<%= pkg.version %>&sentry_key=abc'; | ||
setAuthQueryString(); | ||
assert.strictEqual(authQueryString, expected); | ||
}); | ||
}); | ||
describe('parseDSN', function() { | ||
@@ -389,2 +464,78 @@ it('should do what it advertises', function() { | ||
}); | ||
it('should mark `in_app` for raven.js', function() { | ||
this.sinon.stub(window, 'extractContextFromFrame').returns(undefined); | ||
var frame = { | ||
url: 'http://lol.com/path/raven.js', | ||
line: 10, | ||
column: 11, | ||
func: 'lol' | ||
// context: [] context is stubbed | ||
}; | ||
assert.deepEqual(normalizeFrame(frame), { | ||
filename: 'http://lol.com/path/raven.js', | ||
lineno: 10, | ||
colno: 11, | ||
'function': 'lol', | ||
in_app: false | ||
}); | ||
}); | ||
it('should mark `in_app` for raven.min.js', function() { | ||
this.sinon.stub(window, 'extractContextFromFrame').returns(undefined); | ||
var frame = { | ||
url: 'http://lol.com/path/raven.min.js', | ||
line: 10, | ||
column: 11, | ||
func: 'lol' | ||
// context: [] context is stubbed | ||
}; | ||
assert.deepEqual(normalizeFrame(frame), { | ||
filename: 'http://lol.com/path/raven.min.js', | ||
lineno: 10, | ||
colno: 11, | ||
'function': 'lol', | ||
in_app: false | ||
}); | ||
}); | ||
it('should mark `in_app` for Raven', function() { | ||
this.sinon.stub(window, 'extractContextFromFrame').returns(undefined); | ||
var frame = { | ||
url: 'http://lol.com/path/file.js', | ||
line: 10, | ||
column: 11, | ||
func: 'Raven.wrap' | ||
// context: [] context is stubbed | ||
}; | ||
assert.deepEqual(normalizeFrame(frame), { | ||
filename: 'http://lol.com/path/file.js', | ||
lineno: 10, | ||
colno: 11, | ||
'function': 'Raven.wrap', | ||
in_app: false | ||
}); | ||
}); | ||
it('should mark `in_app` for TraceKit', function() { | ||
this.sinon.stub(window, 'extractContextFromFrame').returns(undefined); | ||
var frame = { | ||
url: 'http://lol.com/path/file.js', | ||
line: 10, | ||
column: 11, | ||
func: 'TraceKit.lol' | ||
// context: [] context is stubbed | ||
}; | ||
assert.deepEqual(normalizeFrame(frame), { | ||
filename: 'http://lol.com/path/file.js', | ||
lineno: 10, | ||
colno: 11, | ||
'function': 'TraceKit.lol', | ||
in_app: false | ||
}); | ||
}); | ||
}); | ||
@@ -572,3 +723,4 @@ | ||
filename: 'http://example.com/override.js', | ||
lineno: 10 | ||
lineno: 10, | ||
in_app: true | ||
}] | ||
@@ -589,3 +741,4 @@ }, | ||
filename: 'http://example.com/override.js', | ||
lineno: 10 | ||
lineno: 10, | ||
in_app: true | ||
}] | ||
@@ -606,3 +759,4 @@ }, | ||
filename: 'http://example.com/override.js', | ||
lineno: 10 | ||
lineno: 10, | ||
in_app: true | ||
}] | ||
@@ -621,3 +775,53 @@ }, | ||
assert.isFalse(window.send.called); | ||
processException('TypeError', '', 'http://example.com', []); | ||
assert.isTrue(window.send.called); | ||
}); | ||
it('should not blow up with `undefined` message', function() { | ||
this.sinon.stub(window, 'send'); | ||
processException('TypeError', undefined, 'http://example.com', []); | ||
assert.isTrue(window.send.called); | ||
}); | ||
it('should truncate messages to the specified length', function() { | ||
this.sinon.stub(window, 'send'); | ||
processException('TypeError', new Array(500).join('a'), 'http://example.com', []); | ||
assert.deepEqual(window.send.lastCall.args, [{ | ||
message: new Array(101).join('a')+'\u2026 at ', | ||
exception: { | ||
type: 'TypeError', | ||
value: new Array(101).join('a')+'\u2026' | ||
}, | ||
stacktrace: { | ||
frames: [{ | ||
filename: 'http://example.com', | ||
lineno: [], | ||
in_app: true | ||
}] | ||
}, | ||
culprit: 'http://example.com', | ||
}]); | ||
globalOptions.maxMessageLength = 150; | ||
processException('TypeError', new Array(500).join('a'), 'http://example.com', []); | ||
assert.deepEqual(window.send.lastCall.args, [{ | ||
message: new Array(151).join('a')+'\u2026 at ', | ||
exception: { | ||
type: 'TypeError', | ||
value: new Array(151).join('a')+'\u2026' | ||
}, | ||
stacktrace: { | ||
frames: [{ | ||
filename: 'http://example.com', | ||
lineno: [], | ||
in_app: true | ||
}] | ||
}, | ||
culprit: 'http://example.com', | ||
}]); | ||
}); | ||
}); | ||
@@ -645,4 +849,3 @@ | ||
globalOptions = { | ||
logger: 'javascript', | ||
site: 'THE BEST' | ||
logger: 'javascript' | ||
}; | ||
@@ -654,3 +857,2 @@ | ||
logger: 'javascript', | ||
site: 'THE BEST', | ||
platform: 'javascript', | ||
@@ -664,3 +866,4 @@ request: { | ||
event_id: 'abc123', | ||
foo: 'bar' | ||
foo: 'bar', | ||
extra: {'session:duration': 100} | ||
}); | ||
@@ -679,4 +882,3 @@ }); | ||
globalOptions = { | ||
logger: 'javascript', | ||
site: 'THE BEST' | ||
logger: 'javascript' | ||
}; | ||
@@ -690,3 +892,2 @@ | ||
logger: 'javascript', | ||
site: 'THE BEST', | ||
platform: 'javascript', | ||
@@ -703,3 +904,4 @@ request: { | ||
}, | ||
foo: 'bar' | ||
foo: 'bar', | ||
extra: {'session:duration': 100} | ||
}]); | ||
@@ -719,3 +921,2 @@ }); | ||
logger: 'javascript', | ||
site: 'THE BEST', | ||
tags: {tag1: 'value1'} | ||
@@ -729,3 +930,2 @@ }; | ||
logger: 'javascript', | ||
site: 'THE BEST', | ||
platform: 'javascript', | ||
@@ -739,4 +939,9 @@ request: { | ||
event_id: 'abc123', | ||
tags: {tag1: 'value1', tag2: 'value2'} | ||
tags: {tag1: 'value1', tag2: 'value2'}, | ||
extra: {'session:duration': 100} | ||
}]); | ||
assert.deepEqual(globalOptions, { | ||
logger: 'javascript', | ||
tags: {tag1: 'value1'} | ||
}); | ||
}); | ||
@@ -755,3 +960,2 @@ | ||
logger: 'javascript', | ||
site: 'THE BEST', | ||
extra: {key1: 'value1'} | ||
@@ -765,3 +969,2 @@ }; | ||
logger: 'javascript', | ||
site: 'THE BEST', | ||
platform: 'javascript', | ||
@@ -775,4 +978,8 @@ request: { | ||
event_id: 'abc123', | ||
extra: {key1: 'value1', key2: 'value2'} | ||
extra: {key1: 'value1', key2: 'value2', 'session:duration': 100} | ||
}]); | ||
assert.deepEqual(globalOptions, { | ||
logger: 'javascript', | ||
extra: {key1: 'value1'} | ||
}); | ||
}); | ||
@@ -787,3 +994,2 @@ | ||
logger: 'javascript', | ||
site: 'THE BEST', | ||
dataCallback: function() { | ||
@@ -803,3 +1009,3 @@ return {lol: 'ibrokeit'}; | ||
it('should strip empty tags/extra', function() { | ||
it('should strip empty tags', function() { | ||
this.sinon.stub(window, 'isSetup').returns(true); | ||
@@ -815,5 +1021,3 @@ this.sinon.stub(window, 'makeRequest'); | ||
logger: 'javascript', | ||
site: 'THE BEST', | ||
tags: {}, | ||
extra: {} | ||
tags: {} | ||
}; | ||
@@ -825,3 +1029,2 @@ | ||
logger: 'javascript', | ||
site: 'THE BEST', | ||
platform: 'javascript', | ||
@@ -835,5 +1038,38 @@ request: { | ||
event_id: 'abc123', | ||
foo: 'bar' | ||
foo: 'bar', | ||
extra: {'session:duration': 100} | ||
}); | ||
}); | ||
it('should attach release if available', 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', | ||
release: 'abc123', | ||
}; | ||
send({foo: 'bar'}); | ||
assert.deepEqual(window.makeRequest.lastCall.args[0], { | ||
project: '2', | ||
release: 'abc123', | ||
logger: 'javascript', | ||
platform: 'javascript', | ||
request: { | ||
url: 'http://localhost/?a=b', | ||
headers: { | ||
'User-Agent': 'lolbrowser' | ||
} | ||
}, | ||
event_id: 'abc123', | ||
foo: 'bar', | ||
extra: {'session:duration': 100} | ||
}); | ||
}); | ||
}); | ||
@@ -844,3 +1080,3 @@ | ||
imageCache = []; | ||
this.sinon.stub(window, 'getAuthQueryString').returns('?lol'); | ||
authQueryString = '?lol'; | ||
globalServer = 'http://localhost/'; | ||
@@ -989,2 +1225,21 @@ | ||
}); | ||
it('should detect 2-words patterns (angularjs frequent case)', function() { | ||
this.sinon.stub(window, 'normalizeFrame').returns(undefined); | ||
this.sinon.stub(window, 'processException'); | ||
var stackInfo = { | ||
name: 'new <anonymous>', | ||
message: 'hey', | ||
url: 'http://example.com', | ||
lineno: 10 | ||
// stack: new Array(2) | ||
}; | ||
handleStackInfo(stackInfo); | ||
assert.isFalse(window.normalizeFrame.called); | ||
assert.deepEqual(window.processException.lastCall.args, [ | ||
'new <anonymous>', 'hey', 'http://example.com', 10, [], undefined | ||
]); | ||
}); | ||
}); | ||
@@ -1024,2 +1279,13 @@ | ||
describe('ignore errors', function() { | ||
it('should install default ignore errors', function() { | ||
Raven.config('//abc@example.com/2'); | ||
assert.isTrue(globalOptions.ignoreErrors.test('Script error'), 'it should install "Script error" by default'); | ||
assert.isTrue(globalOptions.ignoreErrors.test('Script error.'), 'it should install "Script error." by default'); | ||
assert.isTrue(globalOptions.ignoreErrors.test('Javascript error: Script error on line 0'), 'it should install "Javascript error: Script error on line 0" by default'); | ||
assert.isTrue(globalOptions.ignoreErrors.test('Javascript error: Script error. on line 0'), 'it should install "Javascript error: Script error. on line 0" by default'); | ||
}); | ||
}); | ||
describe('callback function', function() { | ||
@@ -1035,8 +1301,7 @@ it('should callback a function if it is global', function() { | ||
Raven.afterLoad(); | ||
afterLoad(); | ||
assert.equal(globalKey, 'random'); | ||
assert.equal(globalServer, 'http://some.other.server:80/api/2/store/'); | ||
assert.isTrue(globalOptions.ignoreErrors.test('Script error'), 'it should install "Script error" by default'); | ||
assert.isTrue(globalOptions.ignoreErrors.test('Script error.'), 'it should install "Script error." by default'); | ||
assert.equal(globalOptions.some, 'config'); | ||
@@ -1057,4 +1322,2 @@ assert.equal(globalProject, '2'); | ||
assert.equal(globalServer, 'http://example.com:80/api/2/store/'); | ||
assert.isTrue(globalOptions.ignoreErrors.test('Script error'), 'it should install "Script error" by default'); | ||
assert.isTrue(globalOptions.ignoreErrors.test('Script error.'), 'it should install "Script error." by default'); | ||
assert.equal(globalOptions.foo, 'bar'); | ||
@@ -1069,4 +1332,2 @@ assert.equal(globalProject, '2'); | ||
assert.equal(globalServer, '//example.com/api/2/store/'); | ||
assert.isTrue(globalOptions.ignoreErrors.test('Script error'), 'it should install "Script error" by default'); | ||
assert.isTrue(globalOptions.ignoreErrors.test('Script error.'), 'it should install "Script error." by default'); | ||
assert.equal(globalProject, '2'); | ||
@@ -1093,2 +1354,11 @@ assert.isTrue(isSetup()); | ||
it('should not set global options more than once', function() { | ||
this.sinon.spy(window, 'parseDSN'); | ||
this.sinon.stub(window, 'logDebug'); | ||
setupRaven(); | ||
setupRaven(); | ||
assert.isTrue(parseDSN.calledOnce); | ||
assert.isTrue(logDebug.called); | ||
}); | ||
describe('whitelistUrls', function() { | ||
@@ -1163,2 +1433,10 @@ it('should be false if none are passed', function() { | ||
}); | ||
it('should not register itself more than once', function() { | ||
this.sinon.stub(window, 'isSetup').returns(true); | ||
this.sinon.stub(TraceKit.report, 'subscribe'); | ||
Raven.install(); | ||
Raven.install(); | ||
assert.isTrue(TraceKit.report.subscribe.calledOnce); | ||
}); | ||
}); | ||
@@ -1235,9 +1513,5 @@ | ||
var error = new Error('lol'); | ||
try { | ||
assert.throws(function() { | ||
Raven.wrap(function() { throw error; })(); | ||
} catch(e) { | ||
return assert.equal(e, error); | ||
} | ||
// Shouldn't hit this | ||
assert.isTrue(false); | ||
}, error); | ||
}); | ||
@@ -1275,7 +1549,5 @@ | ||
this.sinon.stub(Raven, 'captureException'); | ||
try { | ||
Raven.context({'foo': 'bar'}, broken); | ||
} catch(e) { | ||
assert.equal(e, error); | ||
} | ||
assert.throws(function() { | ||
Raven.context({foo: 'bar'}, broken); | ||
}, error); | ||
assert.isTrue(Raven.captureException.called); | ||
@@ -1289,7 +1561,5 @@ assert.deepEqual(Raven.captureException.lastCall.args, [error, {'foo': 'bar'}]); | ||
this.sinon.stub(Raven, 'captureException'); | ||
try { | ||
assert.throws(function() { | ||
Raven.context(broken); | ||
} catch(e) { | ||
assert.equal(e, error); | ||
} | ||
}, error); | ||
assert.isTrue(Raven.captureException.called); | ||
@@ -1320,7 +1590,14 @@ assert.deepEqual(Raven.captureException.lastCall.args, [error, undefined]); | ||
}); | ||
it('should set isRavenInstalled flag to false', function() { | ||
isRavenInstalled = true; | ||
this.sinon.stub(TraceKit.report, 'uninstall'); | ||
Raven.uninstall(); | ||
assert.isFalse(isRavenInstalled); | ||
}); | ||
}); | ||
describe('.setUser', function() { | ||
describe('.setUserContext', function() { | ||
it('should set the globalUser object', function() { | ||
Raven.setUser({name: 'Matt'}); | ||
Raven.setUserContext({name: 'Matt'}); | ||
assert.deepEqual(globalUser, {name: 'Matt'}); | ||
@@ -1331,3 +1608,3 @@ }); | ||
globalUser = {name: 'Matt'}; | ||
Raven.setUser(); | ||
Raven.setUserContext(); | ||
assert.isUndefined(globalUser); | ||
@@ -1337,2 +1614,41 @@ }); | ||
describe('.setExtraContext', function() { | ||
it('should set the globalOptions.extra object', function() { | ||
Raven.setExtraContext({name: 'Matt'}); | ||
assert.deepEqual(globalOptions.extra, {name: 'Matt'}); | ||
}); | ||
it('should clear globalOptions.extra with no arguments', function() { | ||
globalOptions = {name: 'Matt'}; | ||
Raven.setExtraContext(); | ||
assert.deepEqual(globalOptions.extra, {}); | ||
}); | ||
}); | ||
describe('.setTagsContext', function() { | ||
it('should set the globalOptions.tags object', function() { | ||
Raven.setTagsContext({name: 'Matt'}); | ||
assert.deepEqual(globalOptions.tags, {name: 'Matt'}); | ||
}); | ||
it('should clear globalOptions.tags with no arguments', function() { | ||
globalOptions = {name: 'Matt'}; | ||
Raven.setTagsContext(); | ||
assert.deepEqual(globalOptions.tags, {}); | ||
}); | ||
}); | ||
describe('.setReleaseContext', function() { | ||
it('should set the globalOptions.release attribute', function() { | ||
Raven.setReleaseContext('abc123'); | ||
assert.equal(globalOptions.release, 'abc123'); | ||
}); | ||
it('should clear globalOptions.release with no arguments', function() { | ||
globalOptions.release = 'abc123'; | ||
Raven.setReleaseContext(); | ||
assert.isUndefined(globalOptions.release); | ||
}); | ||
}); | ||
describe('.captureMessage', function() { | ||
@@ -1348,2 +1664,10 @@ it('should work as advertised', function() { | ||
it('should coerce message to a string', function() { | ||
this.sinon.stub(window, 'send'); | ||
Raven.captureMessage({}); | ||
assert.deepEqual(window.send.lastCall.args, [{ | ||
message: '[object Object]' | ||
}]); | ||
}); | ||
it('should work as advertised #integration', function() { | ||
@@ -1365,2 +1689,14 @@ imageCache = []; | ||
}); | ||
it('should respect `ignoreErrors`', function() { | ||
this.sinon.stub(window, 'send'); | ||
globalOptions.ignoreErrors = joinRegExp(['e1', 'e2']); | ||
Raven.captureMessage('e1'); | ||
assert.isFalse(window.send.called); | ||
Raven.captureMessage('e2'); | ||
assert.isFalse(window.send.called); | ||
Raven.captureMessage('Non-ignored error'); | ||
assert.isTrue(window.send.calledOnce); | ||
}); | ||
}); | ||
@@ -1395,12 +1731,8 @@ | ||
this.sinon.stub(TraceKit, 'report').throws(error); | ||
try { | ||
assert.throws(function() { | ||
Raven.captureException(new Error('crap2')); | ||
} catch(e) { | ||
return assert.equal(e, error); | ||
} | ||
// shouldn't hit this | ||
assert.isTrue(false); | ||
}, error); | ||
}); | ||
it('should capture as a normal message if a string is passed', function() { | ||
it('should capture as a normal message if a non-Error is passed', function() { | ||
this.sinon.stub(Raven, 'captureMessage'); | ||
@@ -1411,4 +1743,17 @@ this.sinon.stub(TraceKit, 'report'); | ||
assert.isFalse(TraceKit.report.called); | ||
Raven.captureException(true); | ||
assert.equal(Raven.captureMessage.lastCall.args[0], true); | ||
assert.isFalse(TraceKit.report.called); | ||
}); | ||
}); | ||
describe('.isSetup', function() { | ||
it('should work as advertised', function() { | ||
var isSetup = this.sinon.stub(window, 'isSetup'); | ||
isSetup.returns(true); | ||
assert.isTrue(Raven.isSetup()); | ||
isSetup.returns(false); | ||
assert.isFalse(Raven.isSetup()); | ||
}); | ||
}); | ||
}); |
@@ -17,21 +17,3 @@ /* | ||
/** | ||
* 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 isString(what) { | ||
return typeof what === 'string'; | ||
} | ||
function isUndefined(what) { | ||
return typeof what === 'undefined'; | ||
} | ||
/** | ||
@@ -278,3 +260,2 @@ * TraceKit.wrap: Wrap any function in a TraceKit reporter | ||
* Syntax: | ||
* s = TraceKit.computeStackTrace.ofCaller([depth]) | ||
* s = TraceKit.computeStackTrace(exception) // consider using TraceKit.report instead (see below) | ||
@@ -327,15 +308,2 @@ * Returns: | ||
* | ||
* Tracing example: | ||
* function trace(message) { | ||
* var stackInfo = TraceKit.computeStackTrace.ofCaller(); | ||
* var data = message + "\n"; | ||
* for(var i in stackInfo.stack) { | ||
* var item = stackInfo.stack[i]; | ||
* data += (item.func || '[anonymous]') + "() in " + item.url + ":" + (item.line || '0') + "\n"; | ||
* } | ||
* if (window.console) | ||
* console.info(data); | ||
* else | ||
* alert(data); | ||
* } | ||
*/ | ||
@@ -655,4 +623,4 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() { | ||
var chrome = /^\s*at (?:((?:\[object object\])?\S+(?: \[as \S+\])?) )?\(?((?:file|https?):.*?):(\d+)(?::(\d+))?\)?\s*$/i, | ||
gecko = /^\s*(\S*)(?:\((.*?)\))?@((?:file|https?).*?):(\d+)(?::(\d+))?\s*$/i, | ||
var chrome = /^\s*at (.*?) ?\(?((?:file|https?|chrome-extension):.*?):(\d+)(?::(\d+))?\)?\s*$/i, | ||
gecko = /^\s*(.*?)(?:\((.*?)\))?@((?:file|https?|chrome).*?):(\d+)(?::(\d+))?\s*$/i, | ||
lines = ex.stack.split('\n'), | ||
@@ -1074,24 +1042,8 @@ stack = [], | ||
/** | ||
* Logs a stacktrace starting from the previous call and working down. | ||
* @param {(number|string)=} depth How many frames deep to trace. | ||
* @return {Object.<string, *>} Stack trace information. | ||
*/ | ||
function computeStackTraceOfCaller(depth) { | ||
depth = (depth == null ? 0 : +depth) + 1; // "+ 1" because "ofCaller" should drop one frame | ||
try { | ||
throw new Error(); | ||
} catch (ex) { | ||
return computeStackTrace(ex, depth + 1); | ||
} | ||
} | ||
computeStackTrace.augmentStackTraceWithInitialElement = augmentStackTraceWithInitialElement; | ||
computeStackTrace.computeStackTraceFromStackProp = computeStackTraceFromStackProp; | ||
computeStackTrace.guessFunctionName = guessFunctionName; | ||
computeStackTrace.gatherContext = gatherContext; | ||
computeStackTrace.ofCaller = computeStackTraceOfCaller; | ||
return computeStackTrace; | ||
}()); | ||
module.exports = TraceKit; |
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
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Mixed license
License(Experimental) Package contains multiple licenses.
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
294966
53
5444
1
1