Comparing version 2.0.0-rc1 to 2.0.0-rc2
@@ -5,3 +5,8 @@ # Changelog | ||
* CHANGE: Raven.js now wraps functions passed to timer functions, event listeners, and XMLHttpRequest handlers | ||
* CHANGE: Removed jQuery, Backbone, and native plugins (now handled inside raven.js) | ||
* CHANGE: Default HTTP transport changed from `Image` GET to `XMLHttpRequest` POST (w/ CORS) | ||
* CHANGE: When using CommonJS, plugins are initialized via `Raven.addPlugin(require('raven-js/plugins/ember'))` | ||
* CHANGE: Raven builds are generated using Browserify | ||
* NEW: Integration tests (/test/integration/index.html) | ||
@@ -8,0 +13,0 @@ ## 1.3.0 |
@@ -1,3 +0,2 @@ | ||
/*! Raven.js 2.0.0-rc1 (08f64a4) | github.com/getsentry/raven-js */ | ||
!function(a,b){"use strict";function c(){return"undefined"==typeof document?"":document.location.href}function d(a,b){var c,d;if(T){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)m(b,d)&&(c[d]=b[d]);if(document.createEvent)document.dispatchEvent(c);else try{document.fireEvent("on"+c.eventType.toLowerCase(),c)}catch(e){}}}function e(a){this.name="RavenConfigError",this.message=a}function f(a){var b=da.exec(a),c={},d=7;try{for(;d--;)c[ca[d]]=b[d]||""}catch(f){throw new e("Invalid DSN: "+a)}if(c.pass)throw new e("Do not specify your private key in the DSN!");return c}function g(a){return void 0===a}function h(a){return"function"==typeof a}function i(a){return"[object String]"===X.toString.call(a)}function j(a){return"object"==typeof a&&null!==a}function k(a){for(var b in a)return!1;return!0}function l(a){return j(a)&&"[object Error]"===X.toString.call(a)||a instanceof Error}function m(a,b){return X.hasOwnProperty.call(a,b)}function n(a,b){var c,d;if(g(a.length))for(c in a)m(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 o(a,b){var c=[];a.stack&&a.stack.length&&n(a.stack,function(a,b){var d=p(b);d&&c.push(d)}),d("handle",{stackInfo:a,options:b}),r(a.name,a.message,a.url,a.lineno,c,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=!(V.includePaths.test&&!V.includePaths.test(c.filename)||/(Raven|TraceKit)\./.test(c["function"])||/raven\.(min\.)?js$/.test(c.filename)),c}}function q(a){if(a.context&&V.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(g(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;V.ignoreErrors.test&&V.ignoreErrors.test(b)||(b+="",h=a+": "+b,e&&e.length?(c=e[0].filename||c,e.reverse(),g={frames:e}):c&&(g={frames:[{filename:c,lineno:d,in_app:!0}]}),V.ignoreUrls.test&&V.ignoreUrls.test(c)||(!V.whitelistUrls.test||V.whitelistUrls.test(c))&&x(s({exception:{values:[{type:a,value:b,stacktrace:g}]},culprit:c,message:h},f)))}function s(a,b){return b?(n(b,function(b,c){a[b]=c}),a):a}function t(a,b){return a.length<=b?a:a.substr(0,b)+"…"}function u(a){var b=V.maxMessageLength;if(a.message=t(a.message,b),a.exception){var c=a.exception.values[0];c.value=t(c.value,b)}return a}function v(){return+new Date}function w(){if(T&&document.location&&document.location.href){var a={headers:{"User-Agent":navigator.userAgent}};return a.url=document.location.href,document.referrer&&(a.headers.Referer=document.referrer),a}}function x(a){var b={project:Q,logger:V.logger,platform:"javascript"},c=w();c&&(b.request=c),a=s(b,a),a.tags=s(s({},U.tags),a.tags),a.extra=s(s({},U.extra),a.extra),a.extra["session:duration"]=v()-_,k(a.tags)&&delete a.tags,U.user&&(a.user=U.user),V.release&&(a.release=V.release),V.serverName&&(a.server_name=V.serverName),h(V.dataCallback)&&(a=V.dataCallback(a)||a),a&&!k(a)&&(!h(V.shouldSendCallback)||V.shouldSendCallback(a))&&(N=a.event_id||(a.event_id=E()),a=u(a),F("debug","Raven about to send:",a),C()&&(V.transport||A)({url:O,auth:{sentry_version:"7",sentry_client:"raven-js/"+ba.VERSION,sentry_key:P},data:a,options:V,onSuccess:function(){d("success",{data:a,src:O})},onError:function(){d("failure",{data:a,src:O})}}))}function y(a){a.auth.sentry_data=JSON.stringify(a.data);var b=B(),c=a.url+"?"+H(a.auth),d=a.options.crossOrigin;(d||""===d)&&(b.crossOrigin=d),b.onload=a.onSuccess,b.onerror=b.onabort=a.onError,b.src=c}function z(a){function b(){200===c.status?a.onSuccess&&a.onSuccess():a.onError&&a.onError()}var c;c=new XMLHttpRequest,"withCredentials"in c?c.onreadystatechange=function(){4===c.readyState&&b()}:(c=new XDomainRequest,c.onload=b),c.open("POST",a.url+"?"+H(a.auth)),c.send(JSON.stringify(a.data))}function A(a){var b="withCredentials"in new XMLHttpRequest||"undefined"!=typeof XDomainRequest;return(b?z:y)(a)}function B(){return document.createElement("img")}function C(){return S?O?!0:(ea||F("error","Error: Raven has not been configured."),ea=!0,!1):!1}function D(a){for(var b,c=[],d=0,e=a.length;e>d;d++)b=a[d],i(b)?c.push(b.replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")):b&&b.source&&c.push(b.source);return new RegExp(c.join("|"),"i")}function E(){var b=a.crypto||a.msCrypto;if(!g(b)&&b.getRandomValues){var c=new Uint16Array(8);b.getRandomValues(c),c[3]=4095&c[3]|16384,c[4]=16383&c[4]|32768;var d=function(a){for(var b=a.toString(16);b.length<4;)b="0"+b;return b};return d(c[0])+d(c[1])+d(c[2])+d(c[3])+d(c[4])+d(c[5])+d(c[6])+d(c[7])}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 F(a){Z[a]&&ba.debug&&Z[a].apply(Y,K.call(arguments,1))}function G(){var b=a.RavenConfig;b&&ba.config(b.dsn,b.config).install()}function H(a){var b=[];return n(a,function(a,c){b.push(encodeURIComponent(a)+"="+encodeURIComponent(c))}),b.join("&")}function I(a,b){g(b)?delete U[a]:U[a]=s(U[a]||{},b)}var J={remoteFetching:!1,collectWindowErrors:!0,linesOfContext:7,debug:!1},K=[].slice,L="?";J.report=function(){function d(a){i(),p.push(a)}function e(a){for(var b=p.length-1;b>=0;--b)p[b]===a&&p.splice(b,1)}function f(){j(),p=[]}function g(a,b){var c=null;if(!b||J.collectWindowErrors){for(var d in p)if(m(p,d))try{p[d].apply(null,[a].concat(K.call(arguments,2)))}catch(e){c=e}if(c)throw c}}function h(a,b,d,e,f){var h=null;if(s)J.computeStackTrace.augmentStackTraceWithInitialElement(s,b,d,a),k();else if(f)h=J.computeStackTrace(f),g(h,!0);else{var i={url:b,line:d,column:e};i.func=J.computeStackTrace.guessFunctionName(i.url,i.line),i.context=J.computeStackTrace.gatherContext(i.url,i.line),h={message:a,url:c(),stack:[i]},g(h,!0)}return n?n.apply(this,arguments):!1}function i(){o||(n=a.onerror,a.onerror=h,o=!0)}function j(){o&&(a.onerror=n,o=!1,n=b)}function k(){var a=s,b=q;q=null,s=null,r=null,g.apply(null,[a,!1].concat(b))}function l(b,c){var d=K.call(arguments,1);if(s){if(r===b)return;k()}var e=J.computeStackTrace(b);if(s=e,r=b,q=d,a.setTimeout(function(){r===b&&k()},e.incomplete?2e3:0),c!==!1)throw b}var n,o,p=[],q=null,r=null,s=null;return l.subscribe=d,l.unsubscribe=e,l.uninstall=f,l}(),J.computeStackTrace=function(){function b(b){if(!J.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 d(a){if(!i(a))return[];if(!m(u,a)){var c="",d="";try{d=document.domain}catch(e){}-1!==a.indexOf(d)&&(c=b(a)),u[a]=c?c.split("\n"):[]}return u[a]}function e(a,b){var c,e=/function ([^(]*)\(([^)]*)\)/,f=/['"]?([0-9A-Za-z$_]+)['"]?\s*[:=]\s*(function|eval|new Function)/,h="",i=10,j=d(a);if(!j.length)return L;for(var k=0;i>k;++k)if(h=j[b-k]+h,!g(h)){if(c=f.exec(h))return c[1];if(c=e.exec(h))return c[1]}return L}function f(a,b){var c=d(a);if(!c.length)return null;var e=[],f=Math.floor(J.linesOfContext/2),h=f+J.linesOfContext%2,i=Math.max(0,b-f-1),j=Math.min(c.length,b+h-1);b-=1;for(var k=i;j>k;++k)g(c[k])||e.push(c[k]);return e.length>0?e:null}function h(a){return a.replace(/[\-\[\]{}()*+?.,\\\^$|#]/g,"\\$&")}function j(a){return h(a).replace("<","(?:<|<)").replace(">","(?:>|>)").replace("&","(?:&|&)").replace('"','(?:"|")').replace(/\s+/g,"\\s+")}function k(a,b){for(var c,e,f=0,g=b.length;g>f;++f)if((c=d(b[f])).length&&(c=c.join("\n"),e=a.exec(c)))return{url:b[f],line:c.substring(0,e.index).split("\n").length,column:e.index-c.lastIndexOf("\n",e.index)-1};return null}function l(a,b,c){var e,f=d(b),g=new RegExp("\\b"+h(a)+"\\b");return c-=1,f&&f.length>c&&(e=g.exec(f[c]))?e.index:null}function n(b){if("undefined"!=typeof document){for(var c,d,e,f,g=[a.location.href],i=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<i.length;++o){var p=i[o];p.src&&g.push(p.src)}if(e=m.exec(l)){var q=e[1]?"\\s+"+e[1]:"",r=e[2].split(",").join("\\s*,\\s*");c=h(e[3]).replace(/;$/,";?"),d=new RegExp("function"+q+"\\s*\\(\\s*"+r+"\\s*\\)\\s*{\\s*"+c+"\\s*}")}else d=new RegExp(h(l).replace(/\s+/g,"\\s+"));if(f=k(d,g))return f;if(e=n.exec(l)){var s=e[1];if(c=j(e[2]),d=new RegExp("on"+s+"=[\\'\"]\\s*"+c+"\\s*[\\'\"]","i"),f=k(d,g[0]))return f;if(d=new RegExp(c),f=k(d,g))return f}return null}}function o(a){if(!g(a.stack)&&a.stack){for(var b,d,h=/^\s*at (.*?) ?\(?((?:(?:file|https?|chrome-extension):.*?)|<anonymous>):(\d+)(?::(\d+))?\)?\s*$/i,i=/^\s*(.*?)(?:\((.*?)\))?@((?:file|https?|chrome).*?):(\d+)(?::(\d+))?\s*$/i,j=/^\s*at (?:((?:\[object object\])?.+) )?\(?((?:ms-appx|http|https):.*?):(\d+)(?::(\d+))?\)?\s*$/i,k=a.stack.split("\n"),m=[],n=/^(.*) is undefined$/.exec(a.message),o=0,p=k.length;p>o;++o){if(b=i.exec(k[o]))d={url:b[3],func:b[1]||L,args:b[2]?b[2].split(","):"",line:+b[4],column:b[5]?+b[5]:null};else if(b=h.exec(k[o]))d={url:b[2],func:b[1]||L,line:+b[3],column:b[4]?+b[4]:null};else{if(!(b=j.exec(k[o])))continue;d={url:b[2],func:b[1]||L,line:+b[3],column:b[4]?+b[4]:null}}!d.func&&d.line&&(d.func=e(d.url,d.line)),d.line&&(d.context=f(d.url,d.line)),m.push(d)}return m.length?(m[0].line&&!m[0].column&&n?m[0].column=l(n[1],m[0].url,m[0].line):m[0].column||g(a.columnNumber)||(m[0].column=a.columnNumber+1),{name:a.name,message:a.message,url:c(),stack:m}):null}}function p(a){var b=a.stacktrace;if(!g(a.stacktrace)&&a.stacktrace){for(var d,h=/ line (\d+), column (\d+) in (?:<anonymous function: ([^>]+)>|([^\)]+))\((.*)\) in (.*):\s*$/i,i=b.split("\n"),j=[],k=0,l=i.length;l>k;k+=2)if(d=h.exec(i[k])){var m={line:+d[1],column:+d[2],func:d[3]||d[4],args:d[5]?d[5].split(","):[],url:d[6]};if(!m.func&&m.line&&(m.func=e(m.url,m.line)),m.line)try{m.context=f(m.url,m.line)}catch(n){}m.context||(m.context=[i[k+1]]),j.push(m)}return j.length?{name:a.name,message:a.message,url:c(),stack:j}:null}}function q(b){var g=b.message.split("\n");if(g.length<4)return null;var h,i,l,n,o=/^\s*Line (\d+) of linked script ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i,p=/^\s*Line (\d+) of inline#(\d+) script in ((?:file|https?)\S+)(?:: in function (\S+))?\s*$/i,q=/^\s*Line (\d+) of function script\s*$/i,r=[],s=document.getElementsByTagName("script"),t=[];for(i in s)m(s,i)&&!s[i].src&&t.push(s[i]);for(i=2,l=g.length;l>i;i+=2){var u=null;if(h=o.exec(g[i]))u={url:h[2],func:h[3],line:+h[1]};else if(h=p.exec(g[i])){u={url:h[3],func:h[4]};var v=+h[1],w=t[h[2]-1];if(w&&(n=d(u.url))){n=n.join("\n");var x=n.indexOf(w.innerText);x>=0&&(u.line=v+n.substring(0,x).split("\n").length)}}else if(h=q.exec(g[i])){var y=a.location.href.replace(/#.*$/,""),z=h[1],A=new RegExp(j(g[i+1]));n=k(A,[y]),u={url:y,line:n?n.line:z,func:""}}if(u){u.func||(u.func=e(u.url,u.line));var B=f(u.url,u.line),C=B?B[Math.floor(B.length/2)]:null;B&&C.replace(/^\s*/,"")===g[i+1].replace(/^\s*/,"")?u.context=B:u.context=[g[i+1]],r.push(u)}}return r.length?{name:b.name,message:g[0],url:c(),stack:r}:null}function r(a,b,c,d){var g={url:b,line:c};if(g.url&&g.line){a.incomplete=!1,g.func||(g.func=e(g.url,g.line)),g.context||(g.context=f(g.url,g.line));var h=/ '([^']+)' /.exec(d);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 s(a,b){for(var d,f,g,h=/function\s+([_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)?\s*\(/i,i=[],j={},k=!1,m=s.caller;m&&!k;m=m.caller)if(m!==t&&m!==J.report){if(f={url:null,func:L,line:null,column:null},m.name?f.func=m.name:(d=h.exec(m.toString()))&&(f.func=d[1]),"undefined"==typeof f.func)try{f.func=d.input.substring(0,d.input.indexOf("{"))}catch(o){}if(g=n(m)){f.url=g.url,f.line=g.line,f.func===L&&(f.func=e(f.url,f.line));var p=/ '([^']+)' /.exec(a.message||a.description);p&&(f.column=l(p[1],g.url,g.line))}j[""+m]?k=!0:j[""+m]=!0,i.push(f)}b&&i.splice(0,b);var q={name:a.name,message:a.message,url:c(),stack:i};return r(q,a.sourceURL||a.fileName,a.line||a.lineNumber,a.message||a.description),q}function t(a,b){var d=null;b=null==b?0:+b;try{if(d=p(a))return d}catch(e){if(J.debug)throw e}try{if(d=o(a))return d}catch(e){if(J.debug)throw e}try{if(d=q(a))return d}catch(e){if(J.debug)throw e}try{if(d=s(a,b+1))return d}catch(e){if(J.debug)throw e}return{name:a.name,message:a.message,url:c()}}var u={};return t.augmentStackTraceWithInitialElement=r,t.computeStackTraceFromStackProp=o,t.guessFunctionName=e,t.gatherContext=f,t}();var M,N,O,P,Q,R=a.Raven,S=!("object"!=typeof JSON||!JSON.stringify),T="undefined"!=typeof document,U={},V={logger:"javascript",ignoreErrors:[],ignoreUrls:[],whitelistUrls:[],includePaths:[],crossOrigin:"anonymous",collectWindowErrors:!0,maxMessageLength:100},W=!1,X=Object.prototype,Y=a.console||{},Z={},$=[],_=v();for(var aa in Y)Z[aa]=Y[aa];var ba={VERSION:"2.0.0-rc1",debug:!1,noConflict:function(){return a.Raven=R,ba},config:function(a,b){if(O)return F("error","Error: Raven has already been configured"),ba;if(!a)return ba;var c=f(a),d=c.path.lastIndexOf("/"),e=c.path.substr(1,d);return b&&n(b,function(a,b){"tags"==a||"extra"==a?U[a]=b:V[a]=b}),V.ignoreErrors.push(/^Script error\.?$/),V.ignoreErrors.push(/^Javascript error: Script error\.? on line 0$/),V.ignoreErrors=D(V.ignoreErrors),V.ignoreUrls=V.ignoreUrls.length?D(V.ignoreUrls):!1,V.whitelistUrls=V.whitelistUrls.length?D(V.whitelistUrls):!1,V.includePaths=D(V.includePaths),P=c.user,Q=c.path.substr(d+1),O="//"+c.host+(c.port?":"+c.port:"")+"/"+e+"api/"+Q+"/store/",c.protocol&&"app.getsentry.com"!==c.host&&(O=c.protocol+":"+O),V.fetchContext&&(J.remoteFetching=!0),V.linesOfContext&&(J.linesOfContext=V.linesOfContext),J.collectWindowErrors=!!V.collectWindowErrors,ba},install:function(){return C()&&!W&&(J.report.subscribe(o),n($,function(a,b){b()}),W=!0),ba},context:function(a,c,d){return h(a)&&(d=c||[],c=a,a=b),ba.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?ba.wrap(a,arguments[d]):arguments[d];try{return c.apply(this,b)}catch(f){throw ba.captureException(f,a),f}}if(g(c)&&!h(a))return a;if(h(a)&&(c=a,a=b),!h(c))return c;if(c.__raven__)return c;for(var e in c)m(c,e)&&(d[e]=c[e]);return d.prototype=c.prototype,d.__raven__=!0,d.__inner__=c,d},uninstall:function(){return J.report.uninstall(),W=!1,ba},captureException:function(a,b){if(!l(a))return ba.captureMessage(a,b);M=a;try{var c=J.computeStackTrace(a);o(c,b)}catch(d){if(a!==d)throw d}return ba},captureMessage:function(a,b){return V.ignoreErrors.test&&V.ignoreErrors.test(a)?void 0:(x(s({message:a+""},b)),ba)},addPlugin:function(a){return $.push(a),W&&a(),ba},setUserContext:function(a){return U.user=a,ba},setExtraContext:function(a){return I("extra",a),ba},setTagsContext:function(a){return I("tags",a),ba},clearContext:function(){return U={},ba},getContext:function(){return JSON.parse(JSON.stringify(U))},setRelease:function(a){return V.release=a,ba},setDataCallback:function(a){return V.dataCallback=a,ba},setShouldSendCallback:function(a){return V.shouldSendCallback=a,ba},setTransport:function(a){return V.transport=a,ba},lastException:function(){return M},lastEventId:function(){return N},isSetup:function(){return C()}};ba.setUser=ba.setUserContext,ba.setReleaseContext=ba.setRelease;var ca="source protocol user pass host port path".split(" "),da=/^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w\.-]+)(?::(\d+))?(\/.*)/;e.prototype=new Error,e.prototype.constructor=e;var ea;G(),a.Raven=ba,"function"==typeof define&&define.amd?define("raven",[],function(){return ba}):"object"==typeof module?module.exports=ba:"object"==typeof exports&&(exports=ba)}("undefined"!=typeof window?window:this); | ||
!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;b="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,b.Raven=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);var j=new Error("Cannot find module '"+g+"'");throw j.code="MODULE_NOT_FOUND",j}var k=c[g]={exports:{}};b[g][0].call(k.exports,function(a){var c=b[g][1][a];return e(c?c:a)},k,k.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){"use strict";function d(a){this.name="RavenConfigError",this.message=a}d.prototype=new Error,d.prototype.constructor=d,b.exports=d},{}],2:[function(a,b,c){"use strict";function d(){return+new Date}function e(){this._hasJSON=!("object"!=typeof JSON||!JSON.stringify),this._hasDocument="undefined"!=typeof document,this._lastCapturedException=null,this._lastEventId=null,this._globalServer=null,this._globalKey=null,this._globalProject=null,this._globalContext={},this._globalOptions={logger:"javascript",ignoreErrors:[],ignoreUrls:[],whitelistUrls:[],includePaths:[],crossOrigin:"anonymous",collectWindowErrors:!0,maxMessageLength:100},this._ignoreOnError=0,this._isRavenInstalled=!1,this._originalConsole=window.console||{},this._originalConsoleMethods={},this._plugins=[],this._startTime=d();for(var a in this._originalConsole)this._originalConsoleMethods[a]=this._originalConsole[a]}var f=a("../vendor/TraceKit/tracekit"),g=a("./configError"),h=a("./utils"),i=h.isFunction,j=h.isUndefined,k=h.isError,l=h.isEmptyObject,m=h.hasKey,n=h.joinRegExp,o=h.each,p=h.objectMerge,q=h.truncate,r=h.urlencode,s=h.uuid4,t="source protocol user pass host port path".split(" "),u=/^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w\.-]+)(?::(\d+))?(\/.*)/;e.prototype={VERSION:"2.0.0-rc2",debug:!1,TraceKit:f,config:function(a,b){var c=this;if(this._globalServer)return this._logDebug("error","Error: Raven has already been configured"),this;if(!a)return this;var d=this._parseDSN(a),e=d.path.lastIndexOf("/"),g=d.path.substr(1,e);return b&&o(b,function(a,b){"tags"==a||"extra"==a?c._globalContext[a]=b:c._globalOptions[a]=b}),this._globalOptions.ignoreErrors.push(/^Script error\.?$/),this._globalOptions.ignoreErrors.push(/^Javascript error: Script error\.? on line 0$/),this._globalOptions.ignoreErrors=n(this._globalOptions.ignoreErrors),this._globalOptions.ignoreUrls=this._globalOptions.ignoreUrls.length?n(this._globalOptions.ignoreUrls):!1,this._globalOptions.whitelistUrls=this._globalOptions.whitelistUrls.length?n(this._globalOptions.whitelistUrls):!1,this._globalOptions.includePaths=n(this._globalOptions.includePaths),this._globalKey=d.user,this._globalProject=d.path.substr(e+1),this._globalServer="//"+d.host+(d.port?":"+d.port:"")+"/"+g+"api/"+this._globalProject+"/store/",d.protocol&&(this._globalServer=d.protocol+":"+this._globalServer),this._globalOptions.fetchContext&&(f.remoteFetching=!0),this._globalOptions.linesOfContext&&(f.linesOfContext=this._globalOptions.linesOfContext),f.collectWindowErrors=!!this._globalOptions.collectWindowErrors,this},install:function(){var a=this;return this.isSetup()&&!this._isRavenInstalled&&(f.report.subscribe(function(){a._ignoreOnError||a._handleStackInfo.apply(a,arguments)}),this._wrapBuiltIns(),this._drainPlugins(),this._isRavenInstalled=!0),this},context:function(a,b,c){return i(a)&&(c=b||[],b=a,a=void 0),this.wrap(a,b).apply(this,c)},wrap:function(a,b){function c(){for(var c=[],e=arguments.length,f=!a||a&&a.deep!==!1;e--;)c[e]=f?d.wrap(a,arguments[e]):arguments[e];try{return b.apply(this,c)}catch(g){throw d._ignoreNextOnError(),d.captureException(g,a),g}}var d=this;if(j(b)&&!i(a))return a;if(i(a)&&(b=a,a=void 0),!i(b))return b;if(b.__raven__)return b;if(b.__raven_wrapper__)return b.__raven_wrapper__;for(var e in b)m(b,e)&&(c[e]=b[e]);return b.__raven_wrapper__=c,c.prototype=b.prototype,c.__raven__=!0,c.__inner__=b,c},uninstall:function(){return f.report.uninstall(),this._isRavenInstalled=!1,this},captureException:function(a,b){if(!k(a))return this.captureMessage(a,b);this._lastCapturedException=a;try{var c=f.computeStackTrace(a);this._handleStackInfo(c,b)}catch(d){if(a!==d)throw d}return this},captureMessage:function(a,b){return this._globalOptions.ignoreErrors.test&&this._globalOptions.ignoreErrors.test(a)?void 0:(this._send(p({message:a+""},b)),this)},addPlugin:function(a){var b=Array.prototype.slice.call(arguments,1);return this._plugins.push([a,b]),this._isRavenInstalled&&this._drainPlugins(),this},setUserContext:function(a){return this._globalContext.user=a,this},setExtraContext:function(a){return this._mergeContext("extra",a),this},setTagsContext:function(a){return this._mergeContext("tags",a),this},clearContext:function(){return this._globalContext={},this},getContext:function(){return JSON.parse(JSON.stringify(this._globalContext))},setRelease:function(a){return this._globalOptions.release=a,this},setDataCallback:function(a){return this._globalOptions.dataCallback=a,this},setShouldSendCallback:function(a){return this._globalOptions.shouldSendCallback=a,this},setTransport:function(a){return this._globalOptions.transport=a,this},lastException:function(){return this._lastCapturedException},lastEventId:function(){return this._lastEventId},isSetup:function(){return this._hasJSON?this._globalServer?!0:(this.ravenNotConfiguredError||this._logDebug("error","Error: Raven has not been configured."),this.ravenNotConfiguredError=!0,!1):!1},afterLoad:function(){var a=window.RavenConfig;a&&this.config(a.dsn,a.config).install()},_ignoreNextOnError:function(){this._ignoreOnError+=1,setTimeout(function(){this._ignoreOnError-=1})},_triggerEvent:function(a,b){var c,d;if(this._hasDocument){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)m(b,d)&&(c[d]=b[d]);if(document.createEvent)document.dispatchEvent(c);else try{document.fireEvent("on"+c.eventType.toLowerCase(),c)}catch(e){}}},_wrapBuiltIns:function(){function a(a,b,c){var d=a[b];a[b]=c(d)}function b(a){return function(b,d){var e=[].slice.call(arguments),f=e[0];return"function"==typeof f&&(e[0]=c.wrap(f)),a.apply?a.apply(this,e):a(e[0],e[1])}}var c=this;a(window,"setTimeout",b),a(window,"setInterval",b),window.requestAnimationFrame&&a(window,"requestAnimationFrame",function(a){return function(b){a(c.wrap(b))}}),"EventTarget Window Node ApplicationCache AudioTrackList ChannelMergerNode CryptoOperation EventSource FileReader HTMLUnknownElement IDBDatabase IDBRequest IDBTransaction KeyOperation MediaController MessagePort ModalWindow Notification SVGElementInstance Screen TextTrack TextTrackCue TextTrackList WebSocket WebSocketWorker Worker XMLHttpRequest XMLHttpRequestEventTarget XMLHttpRequestUpload".replace(/\w+/g,function(b){var d=window[b]&&window[b].prototype;d&&d.hasOwnProperty&&d.hasOwnProperty("addEventListener")&&(a(d,"addEventListener",function(a){return function(b,d,e,f){try{d&&d.handleEvent&&(d.handleEvent=c.wrap(d.handleEvent))}catch(g){}return a.call(this,b,c.wrap(d),e,f)}}),a(d,"removeEventListener",function(a){return function(b,c,d,e){return c=c&&(c.__raven_wrapper__?c.__raven_wrapper__:c),a.call(this,b,c,d,e)}}))});var d;"XMLHttpRequest"in window&&(d=XMLHttpRequest.prototype.open,XMLHttpRequest.prototype.open=function(b){var e=this;"onreadystatechange onload onerror onprogress".replace(/\w+/g,function(b){b in e&&"[object Function]"===Object.prototype.toString.call(e[b])&&a(e,b,function(a){return c.wrap(a)})}),d.apply(this,arguments)});var e,f=window.jQuery||window.$;f&&f.fn&&f.fn.ready&&(e=f.fn.ready,f.fn.ready=function(a){return e.call(this,c.wrap(a))})},_drainPlugins:function(){var a=this;o(this._plugins,function(b,c){var d=c[0],e=c[1];d.apply(a,[a].concat(e))})},_parseDSN:function(a){var b=u.exec(a),c={},d=7;try{for(;d--;)c[t[d]]=b[d]||""}catch(e){throw new g("Invalid DSN: "+a)}if(c.pass)throw new g("Do not specify your private key in the DSN!");return c},_handleStackInfo:function(a,b){var c=this,d=[];a.stack&&a.stack.length&&o(a.stack,function(a,b){var e=c._normalizeFrame(b);e&&d.push(e)}),this._triggerEvent("handle",{stackInfo:a,options:b}),this._processException(a.name,a.message,a.url,a.lineno,d,b)},_normalizeFrame:function(a){if(a.url){var b,c={filename:a.url,lineno:a.line,colno:a.column,"function":a.func||"?"},d=this._extractContextFromFrame(a);if(d){var e=["pre_context","context_line","post_context"];for(b=3;b--;)c[e[b]]=d[b]}return c.in_app=!(this._globalOptions.includePaths.test&&!this._globalOptions.includePaths.test(c.filename)||/(Raven|TraceKit)\./.test(c["function"])||/raven\.(min\.)?js$/.test(c.filename)),c}},_extractContextFromFrame:function(a){if(a.context&&this._globalOptions.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(j(a.column))return;return[[],b[c].substr(a.column,50),[]]}return[b.slice(0,c),b[c],b.slice(c+1)]}},_processException:function(a,b,c,d,e,f){var g,h;if((!this._globalOptions.ignoreErrors.test||!this._globalOptions.ignoreErrors.test(b))&&(b+="",b=q(b,this._globalOptions.maxMessageLength),h=a+": "+b,h=q(h,this._globalOptions.maxMessageLength),e&&e.length?(c=e[0].filename||c,e.reverse(),g={frames:e}):c&&(g={frames:[{filename:c,lineno:d,in_app:!0}]}),(!this._globalOptions.ignoreUrls.test||!this._globalOptions.ignoreUrls.test(c))&&(!this._globalOptions.whitelistUrls.test||this._globalOptions.whitelistUrls.test(c)))){var i=p({exception:{values:[{type:a,value:b,stacktrace:g}]},culprit:c,message:h},f);this._send(i)}},_trimPacket:function(a){var b=this._globalOptions.maxMessageLength;if(a.message=q(a.message,b),a.exception){var c=a.exception.values[0];c.value=q(c.value,b)}return a},_getHttpData:function(){if(this._hasDocument&&document.location&&document.location.href){var a={headers:{"User-Agent":navigator.userAgent}};return a.url=document.location.href,document.referrer&&(a.headers.Referer=document.referrer),a}},_send:function(a){var b=this,c=this._globalOptions,e={project:this._globalProject,logger:c.logger,platform:"javascript"},f=this._getHttpData();f&&(e.request=f),a=p(e,a),a.tags=p(p({},this._globalContext.tags),a.tags),a.extra=p(p({},this._globalContext.extra),a.extra),a.extra["session:duration"]=d()-this._startTime,l(a.tags)&&delete a.tags,this._globalContext.user&&(a.user=this._globalContext.user),c.release&&(a.release=c.release),c.serverName&&(a.server_name=c.serverName),c.release&&(a.release=c.release),i(c.dataCallback)&&(a=c.dataCallback(a)||a),a&&!l(a)&&(!i(c.shouldSendCallback)||c.shouldSendCallback(a))&&(this._lastEventId=a.event_id||(a.event_id=s()),a=this._trimPacket(a),this._logDebug("debug","Raven about to send:",a),this.isSetup()&&(c.transport||this._makeRequest).call(this,{url:this._globalServer,auth:{sentry_version:"7",sentry_client:"raven-js/"+this.VERSION,sentry_key:this._globalKey},data:a,options:c,onSuccess:function(){b._triggerEvent("success",{data:a,src:b._globalServer})},onError:function(){b._triggerEvent("failure",{data:a,src:b._globalServer})}}))},_makeImageRequest:function(a){a.auth.sentry_data=JSON.stringify(a.data);var b=this._newImage(),c=a.url+"?"+r(a.auth),d=a.options.crossOrigin;(d||""===d)&&(b.crossOrigin=d),b.onload=a.onSuccess,b.onerror=b.onabort=a.onError,b.src=c},_makeXhrRequest:function(a){function b(){200===c.status?a.onSuccess&&a.onSuccess():a.onError&&a.onError()}var c,d=a.url;c=new XMLHttpRequest,"withCredentials"in c?c.onreadystatechange=function(){4===c.readyState&&b()}:(c=new XDomainRequest,d=d.replace(/^https?:/,""),c.onload=b),c.open("POST",d+"?"+r(a.auth)),c.send(JSON.stringify(a.data))},_makeRequest:function(a){var b="withCredentials"in new XMLHttpRequest||"undefined"!=typeof XDomainRequest;return(b?this._makeXhrRequest:this._makeImageRequest)(a)},_newImage:function(){return document.createElement("img")},_logDebug:function(a){this._originalConsoleMethods[a]&&this.debug&&this._originalConsoleMethods[a].apply(this._originalConsole,[].slice.call(arguments,1))},_mergeContext:function(a,b){j(b)?delete this._globalContext[a]:this._globalContext[a]=p(this._globalContext[a]||{},b)}},e.prototype.setUser=e.prototype.setUserContext,e.prototype.setReleaseContext=e.prototype.setRelease,b.exports=e},{"../vendor/TraceKit/tracekit":5,"./configError":1,"./utils":4}],3:[function(a,b,c){"use strict";var d=a("./raven"),e=window.Raven,f=new d;f.noConflict=function(){return window.Raven=e,f},f.afterLoad(),b.exports=f},{"./raven":2}],4:[function(a,b,c){"use strict";function d(a){return void 0===a}function e(a){return"function"==typeof a}function f(a){return"[object String]"===q.toString.call(a)}function g(a){return"object"==typeof a&&null!==a}function h(a){for(var b in a)return!1;return!0}function i(a){return g(a)&&"[object Error]"===q.toString.call(a)||a instanceof Error}function j(a,b){var c,e;if(d(a.length))for(c in a)m(a,c)&&b.call(null,c,a[c]);else if(e=a.length)for(c=0;e>c;c++)b.call(null,c,a[c])}function k(a,b){return b?(j(b,function(b,c){a[b]=c}),a):a}function l(a,b){return a.length<=b?a:a.substr(0,b)+"…"}function m(a,b){return q.hasOwnProperty.call(a,b)}function n(a){for(var b,c=[],d=0,e=a.length;e>d;d++)b=a[d],f(b)?c.push(b.replace(/([.*+?^=!:${}()|\[\]\/\\])/g,"\\$1")):b&&b.source&&c.push(b.source);return new RegExp(c.join("|"),"i")}function o(a){var b=[];return j(a,function(a,c){b.push(encodeURIComponent(a)+"="+encodeURIComponent(c))}),b.join("&")}function p(){var a=window.crypto||window.msCrypto;if(!d(a)&&a.getRandomValues){var b=new Uint16Array(8);a.getRandomValues(b),b[3]=4095&b[3]|16384,b[4]=16383&b[4]|32768;var c=function(a){for(var b=a.toString(16);b.length<4;)b="0"+b;return b};return c(b[0])+c(b[1])+c(b[2])+c(b[3])+c(b[4])+c(b[5])+c(b[6])+c(b[7])}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 q=Object.prototype;b.exports={isUndefined:d,isFunction:e,isString:f,isObject:g,isEmptyObject:h,isError:i,each:j,objectMerge:k,truncate:l,hasKey:m,joinRegExp:n,urlencode:o,uuid4:p}},{}],5:[function(a,b,c){"use strict";function d(){return"undefined"==typeof document?"":document.location.href}var e=a("../../src/utils"),f=e.hasKey,g=e.isString,h=e.isUndefined,i={remoteFetching:!1,collectWindowErrors:!0,linesOfContext:7,debug:!1},j=[].slice,k="?";i.report=function(){function a(a){h(),p.push(a)}function b(a){for(var b=p.length-1;b>=0;--b)p[b]===a&&p.splice(b,1)}function c(){k(),p=[]}function e(a,b){var c=null;if(!b||i.collectWindowErrors){for(var d in p)if(f(p,d))try{p[d].apply(null,[a].concat(j.call(arguments,2)))}catch(e){c=e}if(c)throw c}}function g(a,b,c,f,g){var h=null;if(s)i.computeStackTrace.augmentStackTraceWithInitialElement(s,b,c,a),l();else if(g)h=i.computeStackTrace(g),e(h,!0);else{var j={url:b,line:c,column:f};j.func=i.computeStackTrace.guessFunctionName(j.url,j.line),j.context=i.computeStackTrace.gatherContext(j.url,j.line),h={message:a,url:d(),stack:[j]},e(h,!0)}return n?n.apply(this,arguments):!1}function h(){o||(n=window.onerror,window.onerror=g,o=!0)}function k(){o&&(window.onerror=n,o=!1,n=void 0)}function l(){var a=s,b=q;q=null,s=null,r=null,e.apply(null,[a,!1].concat(b))}function m(a,b){var c=j.call(arguments,1);if(s){if(r===a)return;l()}var d=i.computeStackTrace(a);if(s=d,r=a,q=c,window.setTimeout(function(){r===a&&l()},d.incomplete?2e3:0),b!==!1)throw a}var n,o,p=[],q=null,r=null,s=null;return m.subscribe=a,m.unsubscribe=b,m.uninstall=c,m}(),i.computeStackTrace=function(){function a(a){if(!i.remoteFetching)return"";try{var b=function(){try{return new window.XMLHttpRequest}catch(a){return new window.ActiveXObject("Microsoft.XMLHTTP")}},c=b();return c.open("GET",a,!1),c.send(""),c.responseText}catch(d){return""}}function b(b){if(!g(b))return[];if(!f(v,b)){var c="",d="";try{d=document.domain}catch(e){}-1!==b.indexOf(d)&&(c=a(b)),v[b]=c?c.split("\n"):[]}return v[b]}function c(a,c){var d,e=/function ([^(]*)\(([^)]*)\)/,f=/['"]?([0-9A-Za-z$_]+)['"]?\s*[:=]\s*(function|eval|new Function)/,g="",i=10,j=b(a);if(!j.length)return k;for(var l=0;i>l;++l)if(g=j[c-l]+g,!h(g)){if(d=f.exec(g))return d[1];if(d=e.exec(g))return d[1]}return k}function e(a,c){var d=b(a);if(!d.length)return null;var e=[],f=Math.floor(i.linesOfContext/2),g=f+i.linesOfContext%2,j=Math.max(0,c-f-1),k=Math.min(d.length,c+g-1);c-=1;for(var l=j;k>l;++l)h(d[l])||e.push(d[l]);return e.length>0?e:null}function j(a){return a.replace(/[\-\[\]{}()*+?.,\\\^$|#]/g,"\\$&")}function l(a){return j(a).replace("<","(?:<|<)").replace(">","(?:>|>)").replace("&","(?:&|&)").replace('"','(?:"|")').replace(/\s+/g,"\\s+")}function m(a,c){for(var d,e,f=0,g=c.length;g>f;++f)if((d=b(c[f])).length&&(d=d.join("\n"),e=a.exec(d)))return{url:c[f],line:d.substring(0,e.index).split("\n").length,column:e.index-d.lastIndexOf("\n",e.index)-1};return null}function n(a,c,d){var e,f=b(c),g=new RegExp("\\b"+j(a)+"\\b");return d-=1,f&&f.length>d&&(e=g.exec(f[d]))?e.index:null}function o(a){if("undefined"!=typeof document){for(var b,c,d,e,f=[window.location.href],g=document.getElementsByTagName("script"),h=""+a,i=/^function(?:\s+([\w$]+))?\s*\(([\w\s,]*)\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/,k=/^function on([\w$]+)\s*\(event\)\s*\{\s*(\S[\s\S]*\S)\s*\}\s*$/,n=0;n<g.length;++n){var o=g[n];o.src&&f.push(o.src)}if(d=i.exec(h)){var p=d[1]?"\\s+"+d[1]:"",q=d[2].split(",").join("\\s*,\\s*");b=j(d[3]).replace(/;$/,";?"),c=new RegExp("function"+p+"\\s*\\(\\s*"+q+"\\s*\\)\\s*{\\s*"+b+"\\s*}")}else c=new RegExp(j(h).replace(/\s+/g,"\\s+"));if(e=m(c,f))return e;if(d=k.exec(h)){var r=d[1];if(b=l(d[2]),c=new RegExp("on"+r+"=[\\'\"]\\s*"+b+"\\s*[\\'\"]","i"),e=m(c,f[0]))return e;if(c=new RegExp(b),e=m(c,f))return e}return null}}function p(a){if(!h(a.stack)&&a.stack){for(var b,f,g=/^\s*at (.*?) ?\(?((?:(?:file|https?|chrome-extension):.*?)|<anonymous>):(\d+)(?::(\d+))?\)?\s*$/i,i=/^\s*(.*?)(?:\((.*?)\))?@((?:file|https?|chrome).*?):(\d+)(?::(\d+))?\s*$/i,j=/^\s*at (?:((?:\[object object\])?.+) )?\(?((?:ms-appx|http|https):.*?):(\d+)(?::(\d+))?\)?\s*$/i,l=a.stack.split("\n"),m=[],o=/^(.*) is undefined$/.exec(a.message),p=0,q=l.length;q>p;++p){if(b=i.exec(l[p]))f={url:b[3],func:b[1]||k,args:b[2]?b[2].split(","):"",line:+b[4],column:b[5]?+b[5]:null};else if(b=g.exec(l[p]))f={url:b[2],func:b[1]||k,line:+b[3],column:b[4]?+b[4]:null};else{if(!(b=j.exec(l[p])))continue;f={url:b[2],func:b[1]||k,line:+b[3],column:b[4]?+b[4]:null}}!f.func&&f.line&&(f.func=c(f.url,f.line)),f.line&&(f.context=e(f.url,f.line)),m.push(f)}return m.length?(m[0].line&&!m[0].column&&o?m[0].column=n(o[1],m[0].url,m[0].line):m[0].column||h(a.columnNumber)||(m[0].column=a.columnNumber+1),{name:a.name,message:a.message,url:d(),stack:m}):null}}function q(a){var b=a.stacktrace;if(!h(a.stacktrace)&&a.stacktrace){for(var f,g=/ line (\d+), column (\d+) in (?:<anonymous function: ([^>]+)>|([^\)]+))\((.*)\) in (.*):\s*$/i,i=b.split("\n"),j=[],k=0,l=i.length;l>k;k+=2)if(f=g.exec(i[k])){var m={line:+f[1],column:+f[2],func:f[3]||f[4],args:f[5]?f[5].split(","):[],url:f[6]};if(!m.func&&m.line&&(m.func=c(m.url,m.line)),m.line)try{m.context=e(m.url,m.line)}catch(n){}m.context||(m.context=[i[k+1]]),j.push(m)}return j.length?{name:a.name,message:a.message,url:d(),stack:j}:null}}function r(a){var g=a.message.split("\n");if(g.length<4)return null;var h,i,j,k,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(i in r)f(r,i)&&!r[i].src&&s.push(r[i]);for(i=2,j=g.length;j>i;i+=2){var t=null;if(h=n.exec(g[i]))t={url:h[2],func:h[3],line:+h[1]};else if(h=o.exec(g[i])){t={url:h[3],func:h[4]};var u=+h[1],v=s[h[2]-1];if(v&&(k=b(t.url))){k=k.join("\n");var w=k.indexOf(v.innerText);w>=0&&(t.line=u+k.substring(0,w).split("\n").length)}}else if(h=p.exec(g[i])){var x=window.location.href.replace(/#.*$/,""),y=h[1],z=new RegExp(l(g[i+1]));k=m(z,[x]),t={url:x,line:k?k.line:y,func:""}}if(t){t.func||(t.func=c(t.url,t.line));var A=e(t.url,t.line),B=A?A[Math.floor(A.length/2)]:null;A&&B.replace(/^\s*/,"")===g[i+1].replace(/^\s*/,"")?t.context=A:t.context=[g[i+1]],q.push(t)}}return q.length?{name:a.name,message:g[0],url:d(),stack:q}:null}function s(a,b,d,f){var g={url:b,line:d};if(g.url&&g.line){a.incomplete=!1,g.func||(g.func=c(g.url,g.line)),g.context||(g.context=e(g.url,g.line));var h=/ '([^']+)' /.exec(f);if(h&&(g.column=n(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 t(a,b){for(var e,f,g,h=/function\s+([_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*)?\s*\(/i,j=[],l={},m=!1,p=t.caller;p&&!m;p=p.caller)if(p!==u&&p!==i.report){if(f={url:null,func:k,line:null,column:null},p.name?f.func=p.name:(e=h.exec(p.toString()))&&(f.func=e[1]),"undefined"==typeof f.func)try{f.func=e.input.substring(0,e.input.indexOf("{"))}catch(q){}if(g=o(p)){f.url=g.url,f.line=g.line,f.func===k&&(f.func=c(f.url,f.line));var r=/ '([^']+)' /.exec(a.message||a.description);r&&(f.column=n(r[1],g.url,g.line))}l[""+p]?m=!0:l[""+p]=!0,j.push(f)}b&&j.splice(0,b);var v={name:a.name,message:a.message,url:d(),stack:j};return s(v,a.sourceURL||a.fileName,a.line||a.lineNumber,a.message||a.description),v}function u(a,b){var c=null;b=null==b?0:+b;try{if(c=q(a))return c}catch(e){if(i.debug)throw e}try{if(c=p(a))return c}catch(e){if(i.debug)throw e}try{if(c=r(a))return c}catch(e){if(i.debug)throw e}try{if(c=t(a,b+1))return c}catch(e){if(i.debug)throw e}return{name:a.name,message:a.message,url:d()}}var v={};return u.augmentStackTraceWithInitialElement=s,u.computeStackTraceFromStackProp=p,u.guessFunctionName=c,u.gatherContext=e,u}(),b.exports=i},{"../../src/utils":4}]},{},[3])(3)}); | ||
//# sourceMappingURL=raven.min.map |
{ | ||
"@dist/raven.js": { | ||
"hashes": { | ||
"sha256": "9DAqvZA3nSErbfMqDQAeJZQyZacsXZ7tzQaGK0H4jq8=", | ||
"sha512": "2Wan/WBt/O+JsxQ4a7spzDnUwCXVZOb8rShnoe+NU4tJR/+exrtxoqRYGhCrG2FEB03mMruP7w+uZTinK3Ogjw==" | ||
"sha256": "EcUm8aiNQoLhhyM2Epy81QlYODpcunXBzX9mtf1Nbjo=", | ||
"sha512": "VJn9LcUHpKbaJBDOFZUp2NlporHanMI4OK/0yyRZqUYK9nq+DCqwefeOthmYgr+31CxF90ol9go8hFK6v9Pn8Q==" | ||
}, | ||
"type": null, | ||
"integrity": "sha256-9DAqvZA3nSErbfMqDQAeJZQyZacsXZ7tzQaGK0H4jq8= sha512-2Wan/WBt/O+JsxQ4a7spzDnUwCXVZOb8rShnoe+NU4tJR/+exrtxoqRYGhCrG2FEB03mMruP7w+uZTinK3Ogjw==", | ||
"integrity": "sha256-EcUm8aiNQoLhhyM2Epy81QlYODpcunXBzX9mtf1Nbjo= sha512-VJn9LcUHpKbaJBDOFZUp2NlporHanMI4OK/0yyRZqUYK9nq+DCqwefeOthmYgr+31CxF90ol9go8hFK6v9Pn8Q==", | ||
"path": "dist/raven.js" | ||
@@ -13,9 +13,9 @@ }, | ||
"hashes": { | ||
"sha256": "vGr3ihqzQE0KP2N1mMBkyVX8hNE1AGrC4whZKmgzCe8=", | ||
"sha512": "kTnCyCnWl3hvDs2XYi8FShVtYODsmlO3bEFjT1IkDqnXPLk8IYWGakgi680pZxTuhr/trK7JT6EtngLIZALZeA==" | ||
"sha256": "q5FrfC+Z+HZUD4WALLcwdkbrhTugDMwLrKRHOwPwZek=", | ||
"sha512": "og3Pp6m3d4yz23yziD/J/Kwu1YrBg1obiWNj5nIfwhCVfyxEWYCkO6hXEhVG0h8dmc7R8S4agofwdUJEKCKF3A==" | ||
}, | ||
"type": null, | ||
"integrity": "sha256-vGr3ihqzQE0KP2N1mMBkyVX8hNE1AGrC4whZKmgzCe8= sha512-kTnCyCnWl3hvDs2XYi8FShVtYODsmlO3bEFjT1IkDqnXPLk8IYWGakgi680pZxTuhr/trK7JT6EtngLIZALZeA==", | ||
"integrity": "sha256-q5FrfC+Z+HZUD4WALLcwdkbrhTugDMwLrKRHOwPwZek= sha512-og3Pp6m3d4yz23yziD/J/Kwu1YrBg1obiWNj5nIfwhCVfyxEWYCkO6hXEhVG0h8dmc7R8S4agofwdUJEKCKF3A==", | ||
"path": "dist/raven.min.js" | ||
} | ||
} |
105
Gruntfile.js
@@ -0,1 +1,4 @@ | ||
var proxyquire = require('proxyquireify'); | ||
var versionify = require('browserify-versionify'); | ||
module.exports = function(grunt) { | ||
@@ -6,10 +9,4 @@ "use strict"; | ||
var path = require('path'); | ||
var through = require('through2'); | ||
var coreFiles = [ | ||
'template/_header.js', | ||
'vendor/**/*.js', | ||
'src/**/*.js', | ||
'template/_footer.js' | ||
]; | ||
var excludedPlugins = [ | ||
@@ -30,2 +27,17 @@ 'react-native' | ||
// custom browserify transformer to re-write plugins to | ||
// self-register with Raven via addPlugin | ||
function AddPluginBrowserifyTransformer() { | ||
return function (file) { | ||
return through(function (buf, enc, next) { | ||
buf = buf.toString('utf8'); | ||
if (/plugins/.test(file)) { | ||
buf += "\nrequire('../src/singleton').addPlugin(module.exports);"; | ||
} | ||
this.push(buf); | ||
next(); | ||
}); | ||
}; | ||
} | ||
// Taken from http://dzone.com/snippets/calculate-all-combinations | ||
@@ -70,3 +82,3 @@ var combine = function (a) { | ||
var dest = path.join('build/', key.join(','), '/raven.js'); | ||
dict[dest] = coreFiles.concat(comb); | ||
dict[dest] = ['src/singleton.js'].concat(comb); | ||
@@ -81,14 +93,34 @@ return dict; | ||
clean: ['build'], | ||
concat: { | ||
browserify: { | ||
options: { | ||
separator: '\n', | ||
banner: grunt.file.read('template/_copyright.js'), | ||
process: true | ||
browserifyOptions: { | ||
banner: grunt.file.read('template/_copyright.js'), | ||
standalone: 'Raven' // umd | ||
}, | ||
transform: [versionify] | ||
}, | ||
core: { | ||
src: coreFiles.concat(plugins), | ||
src: 'src/singleton.js', | ||
dest: 'build/raven.js' | ||
}, | ||
all: { | ||
files: pluginConcatFiles | ||
plugins: { | ||
files: pluginConcatFiles, | ||
options: { | ||
transform: [ | ||
[ versionify ], | ||
[ new AddPluginBrowserifyTransformer() ] | ||
] | ||
} | ||
}, | ||
test: { | ||
src: 'test/**/*.test.js', | ||
dest: 'build/raven.test.js', | ||
options: { | ||
browserifyOptions: { | ||
debug: true // source maps | ||
}, | ||
plugin: [proxyquire.plugin] | ||
} | ||
} | ||
@@ -107,3 +139,9 @@ }, | ||
}, | ||
preserveComments: 'some' | ||
preserveComments: 'some', | ||
compress: { | ||
dead_code: true, | ||
global_defs: { | ||
"TEST": false | ||
} | ||
} | ||
}, | ||
@@ -129,14 +167,18 @@ dist: { | ||
mocha: { | ||
all: { | ||
options: { | ||
mocha: { | ||
ignoreLeaks: true, | ||
grep: grunt.option('grep') | ||
}, | ||
log: true, | ||
reporter: 'Dot', | ||
run: true | ||
options: { | ||
mocha: { | ||
ignoreLeaks: true, | ||
grep: grunt.option('grep') | ||
}, | ||
log: true, | ||
reporter: 'Dot', | ||
run: true | ||
}, | ||
unit: { | ||
src: ['test/index.html'], | ||
nonull: true | ||
}, | ||
integration: { | ||
src: ['test/integration/index.html'], | ||
nonull: true | ||
} | ||
@@ -260,3 +302,2 @@ }, | ||
grunt.loadNpmTasks('grunt-contrib-uglify'); | ||
grunt.loadNpmTasks('grunt-contrib-concat'); | ||
grunt.loadNpmTasks('grunt-contrib-clean'); | ||
@@ -268,2 +309,3 @@ grunt.loadNpmTasks('grunt-contrib-jshint'); | ||
// 3rd party Grunt tasks | ||
grunt.loadNpmTasks('grunt-browserify'); | ||
grunt.loadNpmTasks('grunt-mocha'); | ||
@@ -277,6 +319,7 @@ grunt.loadNpmTasks('grunt-release'); | ||
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', 'sri:dist']); | ||
grunt.registerTask('build.all', ['concat.all', 'uglify', 'fixSourceMaps', 'sri:dist', 'sri:build']); | ||
grunt.registerTask('browserify.core', ['_prep', 'browserify:core']); | ||
grunt.registerTask('browserify.plugins', ['_prep', 'browserify:plugins']); | ||
grunt.registerTask('build.test', ['_prep', 'browserify:test']); | ||
grunt.registerTask('build.core', ['browserify.core', 'uglify', 'fixSourceMaps', 'sri:dist']); | ||
grunt.registerTask('build.all', ['browserify.plugins', 'uglify', 'fixSourceMaps', 'sri:dist', 'sri:build']); | ||
grunt.registerTask('build', ['build.all']); | ||
@@ -286,3 +329,3 @@ grunt.registerTask('dist', ['build.core', 'copy:dist']); | ||
// Test task | ||
grunt.registerTask('test', ['jshint', 'mocha']); | ||
grunt.registerTask('test', ['jshint', 'browserify.core', 'browserify:test', 'mocha']); | ||
@@ -289,0 +332,0 @@ // Webserver tasks |
{ | ||
"name": "raven-js", | ||
"version": "2.0.0-rc1", | ||
"version": "2.0.0-rc2", | ||
"license": "BSD-2-Clause", | ||
@@ -14,6 +14,8 @@ "homepage": "https://getsentry.com", | ||
}, | ||
"main": "dist/raven.js", | ||
"main": "src/singleton.js", | ||
"devDependencies": { | ||
"chai": "~1.8.1", | ||
"browserify-versionify": "^1.0.6", | ||
"chai": "2.3.0", | ||
"grunt": "^0.4.5", | ||
"grunt-browserify": "^4.0.1", | ||
"grunt-cli": "~0.1.9", | ||
@@ -31,5 +33,6 @@ "grunt-contrib-clean": "~0.4.0", | ||
"grunt-sri": "mattrobenolt/grunt-sri#pretty", | ||
"jquery": "^2.1.4", | ||
"lodash": "~2.4.0", | ||
"sinon": "~1.7.3" | ||
"proxyquireify": "^3.0.0", | ||
"sinon": "~1.7.3", | ||
"through2": "^2.0.0" | ||
}, | ||
@@ -36,0 +39,0 @@ "keywords": [ |
@@ -6,58 +6,56 @@ /** | ||
*/ | ||
;(function(window) { | ||
'use strict'; | ||
var angular = window.angular, | ||
Raven = window.Raven; | ||
// See https://github.com/angular/angular.js/blob/v1.4.7/src/minErr.js | ||
var angularPattern = /^\[((?:[$a-zA-Z0-9]+:)?(?:[$a-zA-Z0-9]+))\] (.+?)\n(\S+)$/; | ||
// quit if angular isn't on the page | ||
if (!(angular && Raven)) return; | ||
function angularPlugin(Raven, angular) { | ||
/*jshint validthis:true*/ | ||
angular = angular || window.angular; | ||
function RavenProvider() { | ||
this.$get = ['$window', function($window, $log) { | ||
return $window.Raven; | ||
}]; | ||
} | ||
if (!angular) return; | ||
function ExceptionHandlerProvider($provide) { | ||
$provide.decorator('$exceptionHandler', | ||
['Raven', '$delegate', exceptionHandler]); | ||
} | ||
function RavenProvider() { | ||
this.$get = ['$window', function($window) { | ||
return Raven; | ||
}]; | ||
} | ||
function exceptionHandler(Raven, $delegate) { | ||
return function (ex, cause) { | ||
Raven.captureException(ex, { | ||
extra: { cause: cause } | ||
}); | ||
$delegate(ex, cause); | ||
}; | ||
} | ||
function ExceptionHandlerProvider($provide) { | ||
$provide.decorator('$exceptionHandler', | ||
['Raven', '$delegate', exceptionHandler]); | ||
} | ||
// See https://github.com/angular/angular.js/blob/v1.4.7/src/minErr.js | ||
var angularPattern = /^\[((?:[$a-zA-Z0-9]+:)?(?:[$a-zA-Z0-9]+))\] (.+?)\n(\S+)$/; | ||
function exceptionHandler(Raven, $delegate) { | ||
return function (ex, cause) { | ||
Raven.captureException(ex, { | ||
extra: { cause: cause } | ||
}); | ||
$delegate(ex, cause); | ||
}; | ||
} | ||
Raven.addPlugin(function () { | ||
angular.module('ngRaven', []) | ||
.provider('Raven', RavenProvider) | ||
.config(['$provide', ExceptionHandlerProvider]); | ||
}); | ||
Raven.setDataCallback(function(data) { | ||
// We only care about mutating an exception | ||
var exception = data.exception; | ||
if (exception) { | ||
exception = exception.values[0]; | ||
var matches = angularPattern.exec(exception.value); | ||
Raven.setDataCallback(function(data) { | ||
// We only care about mutating an exception | ||
var exception = data.exception; | ||
if (exception) { | ||
exception = exception.values[0]; | ||
var matches = angularPattern.exec(exception.value); | ||
if (matches) { | ||
// This type now becomes something like: $rootScope:inprog | ||
exception.type = matches[1]; | ||
exception.value = matches[2]; | ||
data.message = exception.type + ': ' + exception.value; | ||
// auto set a new tag specifically for the angular error url | ||
data.extra.angularDocs = matches[3].substr(0, 250); | ||
if (matches) { | ||
// This type now becomes something like: $rootScope:inprog | ||
exception.type = matches[1]; | ||
exception.value = matches[2]; | ||
data.message = exception.type + ': ' + exception.value; | ||
// auto set a new tag specifically for the angular error url | ||
data.extra.angularDocs = matches[3].substr(0, 250); | ||
} | ||
} | ||
} | ||
}); | ||
}); | ||
} | ||
}(typeof window !== 'undefined' ? window : this)); | ||
module.exports = angularPlugin; |
@@ -7,47 +7,39 @@ /** | ||
*/ | ||
;(function(window) { | ||
'use strict'; | ||
if (window.Raven) Raven.addPlugin(function ConsolePlugin() { | ||
function consolePlugin(Raven, console) { | ||
console = console || window.console || {}; | ||
var console = window.console || {}; | ||
var originalConsole = console, | ||
logLevels = ['debug', 'info', 'warn', 'error'], | ||
level = logLevels.pop(); | ||
var originalConsole = console, | ||
logLevels = ['debug', 'info', 'warn', 'error'], | ||
level = logLevels.pop(); | ||
var logForGivenLevel = function(level) { | ||
var originalConsoleLevel = console[level]; | ||
var logForGivenLevel = function(level) { | ||
var originalConsoleLevel = console[level]; | ||
// warning level is the only level that doesn't map up | ||
// correctly with what Sentry expects. | ||
if (level === 'warn') level = 'warning'; | ||
return function () { | ||
var args = [].slice.call(arguments); | ||
Raven.captureMessage('' + args[0], {level: level, logger: 'console', extra: { 'arguments': args }}); | ||
// warning level is the only level that doesn't map up | ||
// correctly with what Sentry expects. | ||
if (level === 'warn') level = 'warning'; | ||
return function () { | ||
var args = [].slice.call(arguments); | ||
Raven.captureMessage('' + args[0], {level: level, logger: 'console', extra: { 'arguments': args }}); | ||
// this fails for some browsers. :( | ||
if (originalConsoleLevel) { | ||
// 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); | ||
} | ||
// this fails for some browsers. :( | ||
if (originalConsoleLevel) { | ||
// 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); | ||
} | ||
}; | ||
}; | ||
}; | ||
while(level) { | ||
console[level] = logForGivenLevel(level); | ||
level = logLevels.pop(); | ||
while(level) { | ||
console[level] = logForGivenLevel(level); | ||
level = logLevels.pop(); | ||
} | ||
} | ||
// export | ||
window.console = console; | ||
// End of plugin factory | ||
}); | ||
// console would require `window`, so we don't allow it to be optional | ||
}(window)); | ||
module.exports = consolePlugin; |
@@ -6,30 +6,27 @@ /** | ||
*/ | ||
;(function(window) { | ||
'use strict'; | ||
if (window.Raven) Raven.addPlugin(function EmberPlugin() { | ||
function emberPlugin(Raven, Ember) { | ||
/*jshint validthis:true*/ | ||
Ember = Ember || window.Ember; | ||
var Ember = window.Ember; | ||
// quit if Ember isn't on the page | ||
if (!Ember) return; | ||
// quit if Ember isn't on the page | ||
if (!Ember) return; | ||
var _oldOnError = Ember.onerror; | ||
Ember.onerror = function EmberOnError(error) { | ||
Raven.captureException(error); | ||
if (typeof _oldOnError === 'function') { | ||
_oldOnError.call(this, error); | ||
} | ||
}; | ||
Ember.RSVP.on('error', function (reason) { | ||
if (reason instanceof Error) { | ||
Raven.captureException(reason, {extra: {context: 'Unhandled Promise error detected'}}); | ||
} else { | ||
Raven.captureMessage('Unhandled Promise error detected', {extra: {reason: reason}}); | ||
} | ||
}); | ||
} | ||
var _oldOnError = Ember.onerror; | ||
Ember.onerror = function EmberOnError(error) { | ||
Raven.captureException(error); | ||
if (typeof _oldOnError === 'function') { | ||
_oldOnError.call(this, error); | ||
} | ||
}; | ||
Ember.RSVP.on('error', function (reason) { | ||
if (reason instanceof Error) { | ||
Raven.captureException(reason, {extra: {context: 'Unhandled Promise error detected'}}); | ||
} else { | ||
Raven.captureMessage('Unhandled Promise error detected', {extra: {reason: reason}}); | ||
} | ||
}); | ||
// End of plugin factory | ||
}); | ||
}(typeof window !== 'undefined' ? window : this)); | ||
module.exports = emberPlugin; |
@@ -10,7 +10,6 @@ /*global ErrorUtils:false*/ | ||
*/ | ||
'use strict'; | ||
var DEVICE_PATH_RE = /^\/var\/mobile\/Containers\/Bundle\/Application\/[^\/]+\/[^\.]+\.app/; | ||
function normalizeUrl(url) { | ||
"use strict"; | ||
return url | ||
@@ -21,5 +20,3 @@ .replace(/^file\:\/\//, '') | ||
module.exports = function (Raven) { | ||
"use strict"; | ||
function reactNativePlugin(Raven) { | ||
function urlencode(obj) { | ||
@@ -78,2 +75,4 @@ var pairs = []; | ||
ErrorUtils.setGlobalHandler(Raven.captureException); | ||
}; | ||
} | ||
module.exports = reactNativePlugin; |
@@ -0,1 +1,2 @@ | ||
/*global define*/ | ||
/** | ||
@@ -6,15 +7,11 @@ * require.js plugin | ||
*/ | ||
;(function(window) { | ||
'use strict'; | ||
if (window.Raven) Raven.addPlugin(function RequirePlugin() { | ||
if (typeof define === 'function' && define.amd) { | ||
window.define = Raven.wrap({deep: false}, define); | ||
window.require = Raven.wrap({deep: false}, require); | ||
function requirePlugin(Raven) { | ||
if (typeof define === 'function' && define.amd) { | ||
window.define = Raven.wrap({deep: false}, define); | ||
window.require = Raven.wrap({deep: false}, require); | ||
} | ||
} | ||
// End of plugin factory | ||
}); | ||
}(window)); | ||
module.exports = requirePlugin; |
@@ -5,3 +5,3 @@ # Raven.js [![Build Status](https://travis-ci.org/getsentry/raven-js.svg?branch=master)](https://travis-ci.org/getsentry/raven-js) | ||
**Raven.js v1.3 requires Sentry v7.7.0 or later.** | ||
**Raven.js v2.0 requires Sentry v8.0.0 or later.** | ||
@@ -8,0 +8,0 @@ ## Resources |
1132
src/raven.js
/*global XDomainRequest:false*/ | ||
'use strict'; | ||
var TraceKit = require('../vendor/TraceKit/tracekit'); | ||
var RavenConfigError = require('./configError'); | ||
var utils = require('./utils'); | ||
var isFunction = utils.isFunction; | ||
var isUndefined = utils.isUndefined; | ||
var isError = utils.isError; | ||
var isEmptyObject = utils.isEmptyObject; | ||
var hasKey = utils.hasKey; | ||
var joinRegExp = utils.joinRegExp; | ||
var each = utils.each; | ||
var objectMerge = utils.objectMerge; | ||
var truncate = utils.truncate; | ||
var urlencode = utils.urlencode; | ||
var uuid4 = utils.uuid4; | ||
var dsnKeys = 'source protocol user pass host port path'.split(' '), | ||
dsnPattern = /^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w\.-]+)(?::(\d+))?(\/.*)/; | ||
function now() { | ||
return +new Date(); | ||
} | ||
// 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 _Raven = window.Raven, | ||
hasJSON = !!(typeof JSON === 'object' && JSON.stringify), | ||
function Raven() { | ||
this._hasJSON = !!(typeof JSON === 'object' && JSON.stringify); | ||
// Raven can run in contexts where there's no document (react-native) | ||
hasDocument = typeof document !== 'undefined', | ||
lastCapturedException, | ||
lastEventId, | ||
globalServer, | ||
globalKey, | ||
globalProject, | ||
globalContext = {}, | ||
globalOptions = { | ||
this._hasDocument = typeof document !== 'undefined'; | ||
this._lastCapturedException = null; | ||
this._lastEventId = null; | ||
this._globalServer = null; | ||
this._globalKey = null; | ||
this._globalProject = null; | ||
this._globalContext = {}; | ||
this._globalOptions = { | ||
logger: 'javascript', | ||
@@ -26,15 +49,17 @@ ignoreErrors: [], | ||
maxMessageLength: 100 | ||
}, | ||
isRavenInstalled = false, | ||
objectPrototype = Object.prototype, | ||
}; | ||
this._ignoreOnError = 0; | ||
this._isRavenInstalled = false; | ||
// capture references to window.console *and* all its methods first | ||
// before the console plugin has a chance to monkey patch | ||
originalConsole = window.console || {}, | ||
originalConsoleMethods = {}, | ||
plugins = [], | ||
startTime = now(); | ||
this._originalConsole = window.console || {}; | ||
this._originalConsoleMethods = {}; | ||
this._plugins = []; | ||
this._startTime = now(); | ||
for (var method in originalConsole) { | ||
originalConsoleMethods[method] = originalConsole[method]; | ||
for (var method in this._originalConsole) { | ||
this._originalConsoleMethods[method] = this._originalConsole[method]; | ||
} | ||
} | ||
/* | ||
@@ -45,17 +70,9 @@ * The core Raven singleton | ||
*/ | ||
var Raven = { | ||
VERSION: '<%= pkg.version %>', | ||
Raven.prototype = { | ||
VERSION: '__VERSION__', | ||
debug: false, | ||
/* | ||
* Allow multiple versions of Raven to be installed. | ||
* Strip Raven from the global context and returns the instance. | ||
* | ||
* @return {Raven} | ||
*/ | ||
noConflict: function() { | ||
window.Raven = _Raven; | ||
return Raven; | ||
}, | ||
TraceKit: TraceKit, // alias to TraceKit | ||
@@ -70,9 +87,11 @@ /* | ||
config: function(dsn, options) { | ||
if (globalServer) { | ||
logDebug('error', 'Error: Raven has already been configured'); | ||
return Raven; | ||
var self = this; | ||
if (this._globalServer) { | ||
this._logDebug('error', 'Error: Raven has already been configured'); | ||
return this; | ||
} | ||
if (!dsn) return Raven; | ||
if (!dsn) return this; | ||
var uri = parseDSN(dsn), | ||
var uri = this._parseDSN(dsn), | ||
lastSlash = uri.path.lastIndexOf('/'), | ||
@@ -86,5 +105,5 @@ path = uri.path.substr(1, lastSlash); | ||
if (key == 'tags' || key == 'extra') { | ||
globalContext[key] = value; | ||
self._globalContext[key] = value; | ||
} else { | ||
globalOptions[key] = value; | ||
self._globalOptions[key] = value; | ||
} | ||
@@ -96,37 +115,35 @@ }); | ||
// this is the result of a script being pulled in from an external domain and CORS. | ||
globalOptions.ignoreErrors.push(/^Script error\.?$/); | ||
globalOptions.ignoreErrors.push(/^Javascript error: Script error\.? on line 0$/); | ||
this._globalOptions.ignoreErrors.push(/^Script error\.?$/); | ||
this._globalOptions.ignoreErrors.push(/^Javascript error: Script error\.? on line 0$/); | ||
// join regexp rules into one big rule | ||
globalOptions.ignoreErrors = joinRegExp(globalOptions.ignoreErrors); | ||
globalOptions.ignoreUrls = globalOptions.ignoreUrls.length ? joinRegExp(globalOptions.ignoreUrls) : false; | ||
globalOptions.whitelistUrls = globalOptions.whitelistUrls.length ? joinRegExp(globalOptions.whitelistUrls) : false; | ||
globalOptions.includePaths = joinRegExp(globalOptions.includePaths); | ||
this._globalOptions.ignoreErrors = joinRegExp(this._globalOptions.ignoreErrors); | ||
this._globalOptions.ignoreUrls = this._globalOptions.ignoreUrls.length ? joinRegExp(this._globalOptions.ignoreUrls) : false; | ||
this._globalOptions.whitelistUrls = this._globalOptions.whitelistUrls.length ? joinRegExp(this._globalOptions.whitelistUrls) : false; | ||
this._globalOptions.includePaths = joinRegExp(this._globalOptions.includePaths); | ||
globalKey = uri.user; | ||
globalProject = uri.path.substr(lastSlash + 1); | ||
this._globalKey = uri.user; | ||
this._globalProject = uri.path.substr(lastSlash + 1); | ||
// assemble the endpoint from the uri pieces | ||
globalServer = '//' + uri.host + | ||
this._globalServer = '//' + uri.host + | ||
(uri.port ? ':' + uri.port : '') + | ||
'/' + path + 'api/' + globalProject + '/store/'; | ||
'/' + path + 'api/' + this._globalProject + '/store/'; | ||
// can safely use protocol relative (//) if target host is | ||
// app.getsentry.com; otherwise use protocol from DSN | ||
if (uri.protocol && uri.host !== 'app.getsentry.com') { | ||
globalServer = uri.protocol + ':' + globalServer; | ||
if (uri.protocol) { | ||
this._globalServer = uri.protocol + ':' + this._globalServer; | ||
} | ||
if (globalOptions.fetchContext) { | ||
if (this._globalOptions.fetchContext) { | ||
TraceKit.remoteFetching = true; | ||
} | ||
if (globalOptions.linesOfContext) { | ||
TraceKit.linesOfContext = globalOptions.linesOfContext; | ||
if (this._globalOptions.linesOfContext) { | ||
TraceKit.linesOfContext = this._globalOptions.linesOfContext; | ||
} | ||
TraceKit.collectWindowErrors = !!globalOptions.collectWindowErrors; | ||
TraceKit.collectWindowErrors = !!this._globalOptions.collectWindowErrors; | ||
// return for chaining | ||
return Raven; | ||
return this; | ||
}, | ||
@@ -143,14 +160,19 @@ | ||
install: function() { | ||
if (isSetup() && !isRavenInstalled) { | ||
TraceKit.report.subscribe(handleStackInfo); | ||
var self = this; | ||
if (this.isSetup() && !this._isRavenInstalled) { | ||
TraceKit.report.subscribe(function () { | ||
// maintain 'self' | ||
if (!self._ignoreOnError) { | ||
self._handleStackInfo.apply(self, arguments); | ||
} | ||
}); | ||
this._wrapBuiltIns(); | ||
// Install all of the plugins | ||
each(plugins, function(_, plugin) { | ||
plugin(); | ||
}); | ||
this._drainPlugins(); | ||
isRavenInstalled = true; | ||
this._isRavenInstalled = true; | ||
} | ||
return Raven; | ||
return this; | ||
}, | ||
@@ -173,3 +195,3 @@ | ||
return Raven.wrap(options, func).apply(this, args); | ||
return this.wrap(options, func).apply(this, args); | ||
}, | ||
@@ -185,2 +207,4 @@ | ||
wrap: function(options, func) { | ||
var self = this; | ||
// 1 argument has been passed, and it's not a function | ||
@@ -209,2 +233,7 @@ // so just return it | ||
// If this has already been wrapped in the past, return that | ||
if (func.__raven_wrapper__ ){ | ||
return func.__raven_wrapper__ ; | ||
} | ||
function wrapped() { | ||
@@ -216,3 +245,3 @@ var args = [], i = arguments.length, | ||
while(i--) args[i] = deep ? Raven.wrap(options, arguments[i]) : arguments[i]; | ||
while(i--) args[i] = deep ? self.wrap(options, arguments[i]) : arguments[i]; | ||
@@ -223,3 +252,4 @@ try { | ||
} catch(e) { | ||
Raven.captureException(e, options); | ||
self._ignoreNextOnError(); | ||
self.captureException(e, options); | ||
throw e; | ||
@@ -235,2 +265,4 @@ } | ||
} | ||
func.__raven_wrapper__ = wrapped; | ||
wrapped.prototype = func.prototype; | ||
@@ -253,5 +285,5 @@ | ||
TraceKit.report.uninstall(); | ||
isRavenInstalled = false; | ||
this._isRavenInstalled = false; | ||
return Raven; | ||
return this; | ||
}, | ||
@@ -268,6 +300,6 @@ | ||
// If not an Error is passed through, recall as a message instead | ||
if (!isError(ex)) return Raven.captureMessage(ex, options); | ||
if (!isError(ex)) return this.captureMessage(ex, options); | ||
// Store the raw exception object for potential debugging and introspection | ||
lastCapturedException = ex; | ||
this._lastCapturedException = ex; | ||
@@ -281,3 +313,3 @@ // TraceKit.report will re-raise any exception passed to it, | ||
var stack = TraceKit.computeStackTrace(ex); | ||
handleStackInfo(stack, options); | ||
this._handleStackInfo(stack, options); | ||
} catch(ex1) { | ||
@@ -289,3 +321,3 @@ if(ex !== ex1) { | ||
return Raven; | ||
return this; | ||
}, | ||
@@ -304,3 +336,3 @@ | ||
// probably something you should see: | ||
if (!!globalOptions.ignoreErrors.test && globalOptions.ignoreErrors.test(msg)) { | ||
if (!!this._globalOptions.ignoreErrors.test && this._globalOptions.ignoreErrors.test(msg)) { | ||
return; | ||
@@ -310,3 +342,3 @@ } | ||
// Fire away! | ||
send( | ||
this._send( | ||
objectMerge({ | ||
@@ -317,9 +349,14 @@ message: msg + '' // Make sure it's actually a string | ||
return Raven; | ||
return this; | ||
}, | ||
addPlugin: function(plugin) { | ||
plugins.push(plugin); | ||
if (isRavenInstalled) plugin(); | ||
return Raven; | ||
addPlugin: function(plugin /*arg1, arg2, ... argN*/) { | ||
var pluginArgs = Array.prototype.slice.call(arguments, 1); | ||
this._plugins.push([plugin, pluginArgs]); | ||
if (this._isRavenInstalled) { | ||
this._drainPlugins(); | ||
} | ||
return this; | ||
}, | ||
@@ -335,5 +372,5 @@ | ||
// Intentionally do not merge here since that's an unexpected behavior. | ||
globalContext.user = user; | ||
this._globalContext.user = user; | ||
return Raven; | ||
return this; | ||
}, | ||
@@ -348,5 +385,5 @@ | ||
setExtraContext: function(extra) { | ||
mergeContext('extra', extra); | ||
this._mergeContext('extra', extra); | ||
return Raven; | ||
return this; | ||
}, | ||
@@ -361,5 +398,5 @@ | ||
setTagsContext: function(tags) { | ||
mergeContext('tags', tags); | ||
this._mergeContext('tags', tags); | ||
return Raven; | ||
return this; | ||
}, | ||
@@ -373,5 +410,5 @@ | ||
clearContext: function() { | ||
globalContext = {}; | ||
this._globalContext = {}; | ||
return Raven; | ||
return this; | ||
}, | ||
@@ -386,3 +423,3 @@ | ||
// lol javascript | ||
return JSON.parse(JSON.stringify(globalContext)); | ||
return JSON.parse(JSON.stringify(this._globalContext)); | ||
}, | ||
@@ -397,5 +434,5 @@ | ||
setRelease: function(release) { | ||
globalOptions.release = release; | ||
this._globalOptions.release = release; | ||
return Raven; | ||
return this; | ||
}, | ||
@@ -411,5 +448,5 @@ | ||
setDataCallback: function(callback) { | ||
globalOptions.dataCallback = callback; | ||
this._globalOptions.dataCallback = callback; | ||
return Raven; | ||
return this; | ||
}, | ||
@@ -425,5 +462,5 @@ | ||
setShouldSendCallback: function(callback) { | ||
globalOptions.shouldSendCallback = callback; | ||
this._globalOptions.shouldSendCallback = callback; | ||
return Raven; | ||
return this; | ||
}, | ||
@@ -441,5 +478,5 @@ | ||
setTransport: function(transport) { | ||
globalOptions.transport = transport; | ||
this._globalOptions.transport = transport; | ||
return Raven; | ||
return this; | ||
}, | ||
@@ -453,3 +490,3 @@ | ||
lastException: function() { | ||
return lastCapturedException; | ||
return this._lastCapturedException; | ||
}, | ||
@@ -463,3 +500,3 @@ | ||
lastEventId: function() { | ||
return lastEventId; | ||
return this._lastEventId; | ||
}, | ||
@@ -473,257 +510,312 @@ | ||
isSetup: function() { | ||
return isSetup(); | ||
} | ||
}; | ||
if (!this._hasJSON) return false; // needs JSON support | ||
if (!this._globalServer) { | ||
if (!this.ravenNotConfiguredError) | ||
this._logDebug('error', 'Error: Raven has not been configured.'); | ||
this.ravenNotConfiguredError = true; | ||
return false; | ||
} | ||
return true; | ||
}, | ||
// Deprecations | ||
Raven.setUser = Raven.setUserContext; | ||
Raven.setReleaseContext = Raven.setRelease; | ||
afterLoad: function () { | ||
// TODO: remove window dependence? | ||
function triggerEvent(eventType, options) { | ||
// NOTE: `event` is a native browser thing, so let's avoid conflicting wiht it | ||
var evt, key; | ||
// Attempt to initialize Raven on load | ||
var RavenConfig = window.RavenConfig; | ||
if (RavenConfig) { | ||
this.config(RavenConfig.dsn, RavenConfig.config).install(); | ||
} | ||
}, | ||
if (!hasDocument) | ||
return; | ||
/**** Private functions ****/ | ||
_ignoreNextOnError: function () { | ||
this._ignoreOnError += 1; | ||
setTimeout(function () { | ||
// onerror should trigger before setTimeout | ||
this._ignoreOnError -= 1; | ||
}); | ||
}, | ||
options = options || {}; | ||
_triggerEvent: function(eventType, options) { | ||
// NOTE: `event` is a native browser thing, so let's avoid conflicting wiht it | ||
var evt, key; | ||
eventType = 'raven' + eventType.substr(0,1).toUpperCase() + eventType.substr(1); | ||
if (!this._hasDocument) | ||
return; | ||
if (document.createEvent) { | ||
evt = document.createEvent('HTMLEvents'); | ||
evt.initEvent(eventType, true, true); | ||
} else { | ||
evt = document.createEventObject(); | ||
evt.eventType = eventType; | ||
} | ||
options = options || {}; | ||
for (key in options) if (hasKey(options, key)) { | ||
evt[key] = options[key]; | ||
} | ||
eventType = 'raven' + eventType.substr(0,1).toUpperCase() + eventType.substr(1); | ||
if (document.createEvent) { | ||
// IE9 if standards | ||
document.dispatchEvent(evt); | ||
} else { | ||
// IE8 regardless of Quirks or Standards | ||
// IE9 if quirks | ||
try { | ||
document.fireEvent('on' + evt.eventType.toLowerCase(), evt); | ||
} catch(e) {} | ||
} | ||
} | ||
if (document.createEvent) { | ||
evt = document.createEvent('HTMLEvents'); | ||
evt.initEvent(eventType, true, true); | ||
} else { | ||
evt = document.createEventObject(); | ||
evt.eventType = eventType; | ||
} | ||
var dsnKeys = 'source protocol user pass host port path'.split(' '), | ||
dsnPattern = /^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w\.-]+)(?::(\d+))?(\/.*)/; | ||
for (key in options) if (hasKey(options, key)) { | ||
evt[key] = options[key]; | ||
} | ||
function RavenConfigError(message) { | ||
this.name = 'RavenConfigError'; | ||
this.message = message; | ||
} | ||
RavenConfigError.prototype = new Error(); | ||
RavenConfigError.prototype.constructor = RavenConfigError; | ||
if (document.createEvent) { | ||
// IE9 if standards | ||
document.dispatchEvent(evt); | ||
} else { | ||
// IE8 regardless of Quirks or Standards | ||
// IE9 if quirks | ||
try { | ||
document.fireEvent('on' + evt.eventType.toLowerCase(), evt); | ||
} catch(e) {} | ||
} | ||
}, | ||
/**** Private functions ****/ | ||
function parseDSN(str) { | ||
var m = dsnPattern.exec(str), | ||
dsn = {}, | ||
i = 7; | ||
/** | ||
* Install any queued plugins | ||
*/ | ||
_wrapBuiltIns: function() { | ||
var self = this; | ||
try { | ||
while (i--) dsn[dsnKeys[i]] = m[i] || ''; | ||
} catch(e) { | ||
throw new RavenConfigError('Invalid DSN: ' + str); | ||
} | ||
function fill(obj, name, replacement) { | ||
var orig = obj[name]; | ||
obj[name] = replacement(orig); | ||
} | ||
if (dsn.pass) | ||
throw new RavenConfigError('Do not specify your private key in the DSN!'); | ||
function wrapTimeFn(orig) { | ||
return function (fn, t) { // preserve arity | ||
// Make a copy of the arguments | ||
var args = [].slice.call(arguments); | ||
var originalCallback = args[0]; | ||
if (typeof (originalCallback) === 'function') { | ||
args[0] = self.wrap(originalCallback); | ||
} | ||
return dsn; | ||
} | ||
// 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. | ||
if (orig.apply) { | ||
return orig.apply(this, args); | ||
} else { | ||
return orig(args[0], args[1]); | ||
} | ||
}; | ||
} | ||
function isUndefined(what) { | ||
return what === void 0; | ||
} | ||
fill(window, 'setTimeout', wrapTimeFn); | ||
fill(window, 'setInterval', wrapTimeFn); | ||
if (window.requestAnimationFrame) { | ||
fill(window, 'requestAnimationFrame', function (orig) { | ||
return function (cb) { | ||
orig(self.wrap(cb)); | ||
}; | ||
}); | ||
} | ||
function isFunction(what) { | ||
return typeof what === 'function'; | ||
} | ||
// event targets borrowed from bugsnag-js: | ||
// https://github.com/bugsnag/bugsnag-js/blob/master/src/bugsnag.js#L666 | ||
'EventTarget Window Node ApplicationCache AudioTrackList ChannelMergerNode CryptoOperation EventSource FileReader HTMLUnknownElement IDBDatabase IDBRequest IDBTransaction KeyOperation MediaController MessagePort ModalWindow Notification SVGElementInstance Screen TextTrack TextTrackCue TextTrackList WebSocket WebSocketWorker Worker XMLHttpRequest XMLHttpRequestEventTarget XMLHttpRequestUpload'.replace(/\w+/g, function (global) { | ||
var proto = window[global] && window[global].prototype; | ||
if (proto && proto.hasOwnProperty && proto.hasOwnProperty('addEventListener')) { | ||
fill(proto, 'addEventListener', function(orig) { | ||
return function (evt, fn, capture, secure) { // preserve arity | ||
try { | ||
if (fn && fn.handleEvent) { | ||
fn.handleEvent = self.wrap(fn.handleEvent); | ||
} | ||
} catch (err) {} // can sometimes get 'Permission denied to access property "handle Event' | ||
return orig.call(this, evt, self.wrap(fn), capture, secure); | ||
}; | ||
}); | ||
fill(proto, 'removeEventListener', function (orig) { | ||
return function (evt, fn, capture, secure) { | ||
fn = fn && (fn.__raven_wrapper__ ? fn.__raven_wrapper__ : fn); | ||
return orig.call(this, evt, fn, capture, secure); | ||
}; | ||
}); | ||
} | ||
}); | ||
function isString(what) { | ||
return objectPrototype.toString.call(what) === '[object String]'; | ||
} | ||
var origOpen; | ||
if ('XMLHttpRequest' in window) { | ||
origOpen = XMLHttpRequest.prototype.open; | ||
XMLHttpRequest.prototype.open = function (data) { // preserve arity | ||
var xhr = this; | ||
'onreadystatechange onload onerror onprogress'.replace(/\w+/g, function (prop) { | ||
if (prop in xhr && Object.prototype.toString.call(xhr[prop]) === '[object Function]') { | ||
fill(xhr, prop, function (orig) { | ||
return self.wrap(orig); | ||
}); | ||
} | ||
}); | ||
origOpen.apply(this, arguments); | ||
}; | ||
} | ||
function isObject(what) { | ||
return typeof what === 'object' && what !== null; | ||
} | ||
var $ = window.jQuery || window.$; | ||
var origReady; | ||
if ($ && $.fn && $.fn.ready) { | ||
origReady = $.fn.ready; | ||
$.fn.ready = function ravenjQueryReadyWrapper(fn) { | ||
return origReady.call(this, self.wrap(fn)); | ||
}; | ||
} | ||
}, | ||
function isEmptyObject(what) { | ||
for (var k in what) return false; | ||
return true; | ||
} | ||
_drainPlugins: function() { | ||
var self = this; | ||
// 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; | ||
} | ||
// FIX ME TODO | ||
each(this._plugins, function(_, plugin) { | ||
var installer = plugin[0]; | ||
var args = plugin[1]; | ||
installer.apply(self, [self].concat(args)); | ||
}); | ||
}, | ||
/** | ||
* 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); | ||
} | ||
_parseDSN: function(str) { | ||
var m = dsnPattern.exec(str), | ||
dsn = {}, | ||
i = 7; | ||
function each(obj, callback) { | ||
var i, j; | ||
try { | ||
while (i--) dsn[dsnKeys[i]] = m[i] || ''; | ||
} catch(e) { | ||
throw new RavenConfigError('Invalid DSN: ' + str); | ||
} | ||
if (isUndefined(obj.length)) { | ||
for (i in obj) { | ||
if (hasKey(obj, i)) { | ||
callback.call(null, i, obj[i]); | ||
} | ||
if (dsn.pass) | ||
throw new RavenConfigError('Do not specify your private key in the DSN!'); | ||
return dsn; | ||
}, | ||
_handleStackInfo: function(stackInfo, options) { | ||
var self = this; | ||
var frames = []; | ||
if (stackInfo.stack && stackInfo.stack.length) { | ||
each(stackInfo.stack, function(i, stack) { | ||
var frame = self._normalizeFrame(stack); | ||
if (frame) { | ||
frames.push(frame); | ||
} | ||
}); | ||
} | ||
} else { | ||
j = obj.length; | ||
if (j) { | ||
for (i = 0; i < j; i++) { | ||
callback.call(null, i, obj[i]); | ||
} | ||
} | ||
} | ||
} | ||
function handleStackInfo(stackInfo, options) { | ||
var frames = []; | ||
if (stackInfo.stack && stackInfo.stack.length) { | ||
each(stackInfo.stack, function(i, stack) { | ||
var frame = normalizeFrame(stack); | ||
if (frame) { | ||
frames.push(frame); | ||
} | ||
this._triggerEvent('handle', { | ||
stackInfo: stackInfo, | ||
options: options | ||
}); | ||
} | ||
triggerEvent('handle', { | ||
stackInfo: stackInfo, | ||
options: options | ||
}); | ||
this._processException( | ||
stackInfo.name, | ||
stackInfo.message, | ||
stackInfo.url, | ||
stackInfo.lineno, | ||
frames, | ||
options | ||
); | ||
}, | ||
processException( | ||
stackInfo.name, | ||
stackInfo.message, | ||
stackInfo.url, | ||
stackInfo.lineno, | ||
frames, | ||
options | ||
); | ||
} | ||
_normalizeFrame: function(frame) { | ||
if (!frame.url) return; | ||
function normalizeFrame(frame) { | ||
if (!frame.url) return; | ||
// normalize the frames data | ||
var normalized = { | ||
filename: frame.url, | ||
lineno: frame.line, | ||
colno: frame.column, | ||
'function': frame.func || '?' | ||
}, context = this._extractContextFromFrame(frame), i; | ||
// normalize the frames data | ||
var normalized = { | ||
filename: frame.url, | ||
lineno: frame.line, | ||
colno: frame.column, | ||
'function': frame.func || '?' | ||
}, context = extractContextFromFrame(frame), i; | ||
if (context) { | ||
var keys = ['pre_context', 'context_line', 'post_context']; | ||
i = 3; | ||
while (i--) normalized[keys[i]] = context[i]; | ||
} | ||
if (context) { | ||
var keys = ['pre_context', 'context_line', 'post_context']; | ||
i = 3; | ||
while (i--) normalized[keys[i]] = context[i]; | ||
} | ||
normalized.in_app = !( // determine if an exception came from outside of our app | ||
// first we check the global includePaths list. | ||
(!!this._globalOptions.includePaths.test && !this._globalOptions.includePaths.test(normalized.filename)) || | ||
// Now we check for fun, if the function name is Raven or TraceKit | ||
/(Raven|TraceKit)\./.test(normalized['function']) || | ||
// finally, we do a last ditch effort and check for raven.min.js | ||
/raven\.(min\.)?js$/.test(normalized.filename) | ||
); | ||
normalized.in_app = !( // determine if an exception came from outside of our app | ||
// first we check the global includePaths list. | ||
(!!globalOptions.includePaths.test && !globalOptions.includePaths.test(normalized.filename)) || | ||
// Now we check for fun, if the function name is Raven or TraceKit | ||
/(Raven|TraceKit)\./.test(normalized['function']) || | ||
// finally, we do a last ditch effort and check for raven.min.js | ||
/raven\.(min\.)?js$/.test(normalized.filename) | ||
); | ||
return normalized; | ||
}, | ||
return normalized; | ||
} | ||
_extractContextFromFrame: function(frame) { | ||
// immediately check if we should even attempt to parse a context | ||
if (!frame.context || !this._globalOptions.fetchContext) return; | ||
function extractContextFromFrame(frame) { | ||
// immediately check if we should even attempt to parse a context | ||
if (!frame.context || !globalOptions.fetchContext) return; | ||
var context = frame.context, | ||
pivot = ~~(context.length / 2), | ||
i = context.length, isMinified = false; | ||
var context = frame.context, | ||
pivot = ~~(context.length / 2), | ||
i = context.length, isMinified = false; | ||
while (i--) { | ||
// We're making a guess to see if the source is minified or not. | ||
// To do that, we make the assumption if *any* of the lines passed | ||
// in are greater than 300 characters long, we bail. | ||
// Sentry will see that there isn't a context | ||
if (context[i].length > 300) { | ||
isMinified = true; | ||
break; | ||
} | ||
} | ||
while (i--) { | ||
// We're making a guess to see if the source is minified or not. | ||
// To do that, we make the assumption if *any* of the lines passed | ||
// in are greater than 300 characters long, we bail. | ||
// Sentry will see that there isn't a context | ||
if (context[i].length > 300) { | ||
isMinified = true; | ||
break; | ||
if (isMinified) { | ||
// The source is minified and we don't know which column. Fuck it. | ||
if (isUndefined(frame.column)) return; | ||
// If the source is minified and has a frame column | ||
// we take a chunk of the offending line to hopefully shed some light | ||
return [ | ||
[], // no pre_context | ||
context[pivot].substr(frame.column, 50), // grab 50 characters, starting at the offending column | ||
[] // no post_context | ||
]; | ||
} | ||
} | ||
if (isMinified) { | ||
// The source is minified and we don't know which column. Fuck it. | ||
if (isUndefined(frame.column)) return; | ||
// If the source is minified and has a frame column | ||
// we take a chunk of the offending line to hopefully shed some light | ||
return [ | ||
[], // no pre_context | ||
context[pivot].substr(frame.column, 50), // grab 50 characters, starting at the offending column | ||
[] // no post_context | ||
context.slice(0, pivot), // pre_context | ||
context[pivot], // context_line | ||
context.slice(pivot + 1) // post_context | ||
]; | ||
} | ||
}, | ||
return [ | ||
context.slice(0, pivot), // pre_context | ||
context[pivot], // context_line | ||
context.slice(pivot + 1) // post_context | ||
]; | ||
} | ||
_processException: function(type, message, fileurl, lineno, frames, options) { | ||
var stacktrace, i, fullMessage; | ||
function processException(type, message, fileurl, lineno, frames, options) { | ||
var stacktrace, i, fullMessage; | ||
if (!!this._globalOptions.ignoreErrors.test && this._globalOptions.ignoreErrors.test(message)) return; | ||
if (!!globalOptions.ignoreErrors.test && globalOptions.ignoreErrors.test(message)) return; | ||
message += ''; | ||
message = truncate(message, this._globalOptions.maxMessageLength); | ||
message += ''; | ||
fullMessage = type + ': ' + message; | ||
fullMessage = type + ': ' + message; | ||
fullMessage = truncate(fullMessage, this._globalOptions.maxMessageLength); | ||
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}; | ||
} else if (fileurl) { | ||
stacktrace = { | ||
frames: [{ | ||
filename: fileurl, | ||
lineno: lineno, | ||
in_app: true | ||
}] | ||
}; | ||
} | ||
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}; | ||
} else if (fileurl) { | ||
stacktrace = { | ||
frames: [{ | ||
filename: fileurl, | ||
lineno: lineno, | ||
in_app: true | ||
}] | ||
}; | ||
} | ||
if (!!globalOptions.ignoreUrls.test && globalOptions.ignoreUrls.test(fileurl)) return; | ||
if (!!globalOptions.whitelistUrls.test && !globalOptions.whitelistUrls.test(fileurl)) return; | ||
if (!!this._globalOptions.ignoreUrls.test && this._globalOptions.ignoreUrls.test(fileurl)) return; | ||
if (!!this._globalOptions.whitelistUrls.test && !this._globalOptions.whitelistUrls.test(fileurl)) return; | ||
// Fire away! | ||
send( | ||
objectMerge({ | ||
var data = objectMerge({ | ||
// sentry.interfaces.Exception | ||
@@ -739,304 +831,220 @@ exception: { | ||
message: fullMessage | ||
}, options) | ||
); | ||
} | ||
}, options); | ||
function objectMerge(obj1, obj2) { | ||
if (!obj2) { | ||
return obj1; | ||
} | ||
each(obj2, function(key, value){ | ||
obj1[key] = value; | ||
}); | ||
return obj1; | ||
} | ||
// Fire away! | ||
this._send(data); | ||
}, | ||
function truncate(str, max) { | ||
return str.length <= max ? str : str.substr(0, max) + '\u2026'; | ||
} | ||
_trimPacket: function(data) { | ||
// For now, we only want to truncate the two different messages | ||
// but this could/should be expanded to just trim everything | ||
var max = this._globalOptions.maxMessageLength; | ||
data.message = truncate(data.message, max); | ||
if (data.exception) { | ||
var exception = data.exception.values[0]; | ||
exception.value = truncate(exception.value, max); | ||
} | ||
function trimPacket(data) { | ||
// For now, we only want to truncate the two different messages | ||
// but this could/should be expanded to just trim everything | ||
var max = globalOptions.maxMessageLength; | ||
data.message = truncate(data.message, max); | ||
if (data.exception) { | ||
var exception = data.exception.values[0]; | ||
exception.value = truncate(exception.value, max); | ||
} | ||
return data; | ||
}, | ||
return data; | ||
} | ||
_getHttpData: function() { | ||
if (!this._hasDocument || !document.location || !document.location.href) { | ||
return; | ||
} | ||
function now() { | ||
return +new Date(); | ||
} | ||
var httpData = { | ||
headers: { | ||
'User-Agent': navigator.userAgent | ||
} | ||
}; | ||
function getHttpData() { | ||
if (!hasDocument || !document.location || !document.location.href) { | ||
return; | ||
} | ||
httpData.url = document.location.href; | ||
var httpData = { | ||
headers: { | ||
'User-Agent': navigator.userAgent | ||
if (document.referrer) { | ||
httpData.headers.Referer = document.referrer; | ||
} | ||
}; | ||
httpData.url = document.location.href; | ||
return httpData; | ||
}, | ||
if (document.referrer) { | ||
httpData.headers.Referer = document.referrer; | ||
} | ||
return httpData; | ||
} | ||
_send: function(data) { | ||
var self = this; | ||
function send(data) { | ||
var baseData = { | ||
project: globalProject, | ||
logger: globalOptions.logger, | ||
platform: 'javascript' | ||
}, httpData = getHttpData(); | ||
var globalOptions = this._globalOptions; | ||
if (httpData) { | ||
baseData.request = httpData; | ||
} | ||
var baseData = { | ||
project: this._globalProject, | ||
logger: globalOptions.logger, | ||
platform: 'javascript' | ||
}, httpData = this._getHttpData(); | ||
data = objectMerge(baseData, data); | ||
if (httpData) { | ||
baseData.request = httpData; | ||
} | ||
// Merge in the tags and extra separately since objectMerge doesn't handle a deep merge | ||
data.tags = objectMerge(objectMerge({}, globalContext.tags), data.tags); | ||
data.extra = objectMerge(objectMerge({}, globalContext.extra), data.extra); | ||
data = objectMerge(baseData, data); | ||
// Send along our own collected metadata with extra | ||
data.extra['session:duration'] = now() - startTime; | ||
// Merge in the tags and extra separately since objectMerge doesn't handle a deep merge | ||
data.tags = objectMerge(objectMerge({}, this._globalContext.tags), data.tags); | ||
data.extra = objectMerge(objectMerge({}, this._globalContext.extra), data.extra); | ||
// If there are no tags/extra, strip the key from the payload alltogther. | ||
if (isEmptyObject(data.tags)) delete data.tags; | ||
// Send along our own collected metadata with extra | ||
data.extra['session:duration'] = now() - this._startTime; | ||
if (globalContext.user) { | ||
// sentry.interfaces.User | ||
data.user = globalContext.user; | ||
} | ||
// If there are no tags/extra, strip the key from the payload alltogther. | ||
if (isEmptyObject(data.tags)) delete data.tags; | ||
// Include the release if it's defined in globalOptions | ||
if (globalOptions.release) data.release = globalOptions.release; | ||
// Include server_name if it's defined in globalOptions | ||
if (globalOptions.serverName) data.server_name = globalOptions.serverName; | ||
if (this._globalContext.user) { | ||
// sentry.interfaces.User | ||
data.user = this._globalContext.user; | ||
} | ||
if (isFunction(globalOptions.dataCallback)) { | ||
data = globalOptions.dataCallback(data) || data; | ||
} | ||
// Include the release if it's defined in globalOptions | ||
if (globalOptions.release) data.release = globalOptions.release; | ||
// Include server_name if it's defined in globalOptions | ||
if (globalOptions.serverName) data.server_name = globalOptions.serverName; | ||
// Why?????????? | ||
if (!data || isEmptyObject(data)) { | ||
return; | ||
} | ||
// Include the release if it's defined in globalOptions | ||
if (globalOptions.release) data.release = globalOptions.release; | ||
// Check if the request should be filtered or not | ||
if (isFunction(globalOptions.shouldSendCallback) && !globalOptions.shouldSendCallback(data)) { | ||
return; | ||
} | ||
if (isFunction(globalOptions.dataCallback)) { | ||
data = globalOptions.dataCallback(data) || data; | ||
} | ||
// 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 = uuid4()); | ||
// Why?????????? | ||
if (!data || isEmptyObject(data)) { | ||
return; | ||
} | ||
// Try and clean up the packet before sending by truncating long values | ||
data = trimPacket(data); | ||
logDebug('debug', 'Raven about to send:', data); | ||
if (!isSetup()) return; | ||
(globalOptions.transport || makeRequest)({ | ||
url: globalServer, | ||
auth: { | ||
sentry_version: '7', | ||
sentry_client: 'raven-js/' + Raven.VERSION, | ||
sentry_key: globalKey | ||
}, | ||
data: data, | ||
options: globalOptions, | ||
onSuccess: function success() { | ||
triggerEvent('success', { | ||
data: data, | ||
src: globalServer | ||
}); | ||
}, | ||
onError: function failure() { | ||
triggerEvent('failure', { | ||
data: data, | ||
src: globalServer | ||
}); | ||
// Check if the request should be filtered or not | ||
if (isFunction(globalOptions.shouldSendCallback) && !globalOptions.shouldSendCallback(data)) { | ||
return; | ||
} | ||
}); | ||
} | ||
function makeImageRequest(opts) { | ||
// Tack on sentry_data to auth options, which get urlencoded | ||
opts.auth.sentry_data = JSON.stringify(opts.data); | ||
// 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 | ||
this._lastEventId = data.event_id || (data.event_id = uuid4()); | ||
var img = newImage(), | ||
src = opts.url + '?' + urlencode(opts.auth), | ||
crossOrigin = opts.options.crossOrigin; | ||
// Try and clean up the packet before sending by truncating long values | ||
data = this._trimPacket(data); | ||
if (crossOrigin || crossOrigin === '') { | ||
img.crossOrigin = crossOrigin; | ||
} | ||
img.onload = opts.onSuccess; | ||
img.onerror = img.onabort = opts.onError; | ||
img.src = src; | ||
} | ||
this._logDebug('debug', 'Raven about to send:', data); | ||
function makeXhrRequest(opts) { | ||
var request; | ||
if (!this.isSetup()) return; | ||
function handler() { | ||
if (request.status === 200) { | ||
if (opts.onSuccess) { | ||
opts.onSuccess(); | ||
(globalOptions.transport || this._makeRequest).call(this, { | ||
url: this._globalServer, | ||
auth: { | ||
sentry_version: '7', | ||
sentry_client: 'raven-js/' + this.VERSION, | ||
sentry_key: this._globalKey | ||
}, | ||
data: data, | ||
options: globalOptions, | ||
onSuccess: function success() { | ||
self._triggerEvent('success', { | ||
data: data, | ||
src: self._globalServer | ||
}); | ||
}, | ||
onError: function failure() { | ||
self._triggerEvent('failure', { | ||
data: data, | ||
src: self._globalServer | ||
}); | ||
} | ||
} else if (opts.onError) { | ||
opts.onError(); | ||
} | ||
} | ||
}); | ||
}, | ||
request = new XMLHttpRequest(); | ||
if ('withCredentials' in request) { | ||
request.onreadystatechange = function () { | ||
if (request.readyState !== 4) { | ||
return; | ||
} | ||
handler(); | ||
}; | ||
} else { | ||
request = new XDomainRequest(); | ||
// onreadystatechange not supported by XDomainRequest | ||
request.onload = handler; | ||
} | ||
_makeImageRequest: function(opts) { | ||
// Tack on sentry_data to auth options, which get urlencoded | ||
opts.auth.sentry_data = JSON.stringify(opts.data); | ||
// NOTE: auth is intentionally sent as part of query string (NOT as custom | ||
// HTTP header) so as to avoid preflight CORS requests | ||
request.open('POST', opts.url + '?' + urlencode(opts.auth)); | ||
request.send(JSON.stringify(opts.data)); | ||
} | ||
var img = this._newImage(), | ||
src = opts.url + '?' + urlencode(opts.auth), | ||
crossOrigin = opts.options.crossOrigin; | ||
function makeRequest(opts) { | ||
var hasCORS = | ||
'withCredentials' in new XMLHttpRequest() || | ||
typeof XDomainRequest !== 'undefined'; | ||
if (crossOrigin || crossOrigin === '') { | ||
img.crossOrigin = crossOrigin; | ||
} | ||
img.onload = opts.onSuccess; | ||
img.onerror = img.onabort = opts.onError; | ||
img.src = src; | ||
}, | ||
return (hasCORS ? makeXhrRequest : makeImageRequest)(opts); | ||
} | ||
_makeXhrRequest: function(opts) { | ||
var request; | ||
// Note: this is shitty, but I can't figure out how to get | ||
// sinon to stub document.createElement without breaking everything | ||
// so this wrapper is just so I can stub it for tests. | ||
function newImage() { | ||
return document.createElement('img'); | ||
} | ||
var url = opts.url; | ||
function handler() { | ||
if (request.status === 200) { | ||
if (opts.onSuccess) { | ||
opts.onSuccess(); | ||
} | ||
} else if (opts.onError) { | ||
opts.onError(); | ||
} | ||
} | ||
var ravenNotConfiguredError; | ||
request = new XMLHttpRequest(); | ||
if ('withCredentials' in request) { | ||
request.onreadystatechange = function () { | ||
if (request.readyState !== 4) { | ||
return; | ||
} | ||
handler(); | ||
}; | ||
} else { | ||
request = new XDomainRequest(); | ||
// xdomainrequest cannot go http -> https (or vice versa), | ||
// so always use protocol relative | ||
url = url.replace(/^https?:/, ''); | ||
function isSetup() { | ||
if (!hasJSON) return false; // needs JSON support | ||
if (!globalServer) { | ||
if (!ravenNotConfiguredError) | ||
logDebug('error', 'Error: Raven has not been configured.'); | ||
ravenNotConfiguredError = true; | ||
return false; | ||
} | ||
return true; | ||
} | ||
function joinRegExp(patterns) { | ||
// Combine an array of regular expressions and strings into one large regexp | ||
// Be mad. | ||
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 | ||
sources.push(pattern.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1")); | ||
} else if (pattern && pattern.source) { | ||
// If it's a regexp already, we want to extract the source | ||
sources.push(pattern.source); | ||
// onreadystatechange not supported by XDomainRequest | ||
request.onload = handler; | ||
} | ||
// Intentionally skip other cases | ||
} | ||
return new RegExp(sources.join('|'), 'i'); | ||
} | ||
function uuid4() { | ||
var crypto = window.crypto || window.msCrypto; | ||
// NOTE: auth is intentionally sent as part of query string (NOT as custom | ||
// HTTP header) so as to avoid preflight CORS requests | ||
request.open('POST', url + '?' + urlencode(opts.auth)); | ||
request.send(JSON.stringify(opts.data)); | ||
}, | ||
if (!isUndefined(crypto) && crypto.getRandomValues) { | ||
// Use window.crypto API if available | ||
var arr = new Uint16Array(8); | ||
crypto.getRandomValues(arr); | ||
_makeRequest: function(opts) { | ||
var hasCORS = | ||
'withCredentials' in new XMLHttpRequest() || | ||
typeof XDomainRequest !== 'undefined'; | ||
// set 4 in byte 7 | ||
arr[3] = arr[3] & 0xFFF | 0x4000; | ||
// set 2 most significant bits of byte 9 to '10' | ||
arr[4] = arr[4] & 0x3FFF | 0x8000; | ||
return (hasCORS ? this._makeXhrRequest : this._makeImageRequest)(opts); | ||
}, | ||
var pad = function(num) { | ||
var v = num.toString(16); | ||
while (v.length < 4) { | ||
v = '0' + v; | ||
} | ||
return v; | ||
}; | ||
// Note: this is shitty, but I can't figure out how to get | ||
// sinon to stub document.createElement without breaking everything | ||
// so this wrapper is just so I can stub it for tests. | ||
_newImage: function() { | ||
return document.createElement('img'); | ||
}, | ||
return (pad(arr[0]) + pad(arr[1]) + pad(arr[2]) + pad(arr[3]) + pad(arr[4]) + | ||
pad(arr[5]) + pad(arr[6]) + pad(arr[7])); | ||
} else { | ||
// http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/2117523#2117523 | ||
return 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function(c) { | ||
var r = Math.random()*16|0, | ||
v = c == 'x' ? r : (r&0x3|0x8); | ||
return v.toString(16); | ||
}); | ||
} | ||
} | ||
_logDebug: function(level) { | ||
if (this._originalConsoleMethods[level] && this.debug) { | ||
this._originalConsoleMethods[level].apply(this._originalConsole, [].slice.call(arguments, 1)); | ||
} | ||
}, | ||
function logDebug(level) { | ||
if (originalConsoleMethods[level] && Raven.debug) { | ||
// _slice is coming from vendor/TraceKit/tracekit.js | ||
// so it's accessible globally | ||
originalConsoleMethods[level].apply(originalConsole, _slice.call(arguments, 1)); | ||
_mergeContext: function(key, context) { | ||
if (isUndefined(context)) { | ||
delete this._globalContext[key]; | ||
} else { | ||
this._globalContext[key] = objectMerge(this._globalContext[key] || {}, context); | ||
} | ||
} | ||
} | ||
}; | ||
function afterLoad() { | ||
// Attempt to initialize Raven on load | ||
var RavenConfig = window.RavenConfig; | ||
if (RavenConfig) { | ||
Raven.config(RavenConfig.dsn, RavenConfig.config).install(); | ||
} | ||
} | ||
// Deprecations | ||
Raven.prototype.setUser = Raven.prototype.setUserContext; | ||
Raven.prototype.setReleaseContext = Raven.prototype.setRelease; | ||
function urlencode(o) { | ||
var pairs = []; | ||
each(o, function(key, value) { | ||
pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(value)); | ||
}); | ||
return pairs.join('&'); | ||
} | ||
function mergeContext(key, context) { | ||
if (isUndefined(context)) { | ||
delete globalContext[key]; | ||
} else { | ||
globalContext[key] = objectMerge(globalContext[key] || {}, context); | ||
} | ||
} | ||
afterLoad(); | ||
module.exports = Raven; |
@@ -0,1 +1,9 @@ | ||
'use strict'; | ||
var utils = require('../../src/utils'); | ||
var hasKey = utils.hasKey; | ||
var isString = utils.isString; | ||
var isUndefined = utils.isUndefined; | ||
/* | ||
@@ -18,3 +26,2 @@ TraceKit - Cross brower stack traces - github.com/occ/TraceKit | ||
function getLocationHref() { | ||
@@ -25,3 +32,3 @@ if (typeof document === 'undefined') | ||
return document.location.href; | ||
}; | ||
} | ||
@@ -1057,1 +1064,3 @@ /** | ||
}()); | ||
module.exports = TraceKit; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
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
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
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
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
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
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
463566
70
6972
0
20
2
6