Update Raven.js

pull/459/merge
Thibaut Courouble 9 years ago
parent c2dcd3d1b8
commit 5db1ca7cd5

@ -1,4 +1,4 @@
/*! Raven.js 3.0.4 (0784c3c) | github.com/getsentry/raven-js */ /*! Raven.js 3.5.1 (bef9fa7) | github.com/getsentry/raven-js */
/* /*
* Includes TraceKit * Includes TraceKit
@ -11,6 +11,35 @@
*/ */
(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Raven = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Raven = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
exports = module.exports = stringify
exports.getSerialize = serializer
function stringify(obj, replacer, spaces, cycleReplacer) {
return JSON.stringify(obj, serializer(replacer, cycleReplacer), spaces)
}
function serializer(replacer, cycleReplacer) {
var stack = [], keys = []
if (cycleReplacer == null) cycleReplacer = function(key, value) {
if (stack[0] === value) return "[Circular ~]"
return "[Circular ~." + keys.slice(0, stack.indexOf(value)).join(".") + "]"
}
return function(key, value) {
if (stack.length > 0) {
var thisPos = stack.indexOf(this)
~thisPos ? stack.splice(thisPos + 1) : stack.push(this)
~thisPos ? keys.splice(thisPos, Infinity, key) : keys.push(key)
if (~stack.indexOf(value)) value = cycleReplacer.call(this, key, value)
}
else stack.push(value)
return replacer == null ? value : replacer.call(this, key, value)
}
}
},{}],2:[function(_dereq_,module,exports){
'use strict'; 'use strict';
function RavenConfigError(message) { function RavenConfigError(message) {
@ -22,7 +51,7 @@ RavenConfigError.prototype.constructor = RavenConfigError;
module.exports = RavenConfigError; module.exports = RavenConfigError;
},{}],2:[function(_dereq_,module,exports){ },{}],3:[function(_dereq_,module,exports){
'use strict'; 'use strict';
var wrapMethod = function(console, level, callback) { var wrapMethod = function(console, level, callback) {
@ -61,13 +90,14 @@ module.exports = {
wrapMethod: wrapMethod wrapMethod: wrapMethod
}; };
},{}],3:[function(_dereq_,module,exports){ },{}],4:[function(_dereq_,module,exports){
/*global XDomainRequest:false*/ /*global XDomainRequest:false*/
'use strict'; 'use strict';
var TraceKit = _dereq_(6); var TraceKit = _dereq_(7);
var RavenConfigError = _dereq_(1); var RavenConfigError = _dereq_(2);
var utils = _dereq_(5); var utils = _dereq_(6);
var stringify = _dereq_(1);
var isFunction = utils.isFunction; var isFunction = utils.isFunction;
var isUndefined = utils.isUndefined; var isUndefined = utils.isUndefined;
@ -83,8 +113,9 @@ var uuid4 = utils.uuid4;
var htmlTreeAsString = utils.htmlTreeAsString; var htmlTreeAsString = utils.htmlTreeAsString;
var parseUrl = utils.parseUrl; var parseUrl = utils.parseUrl;
var isString = utils.isString; var isString = utils.isString;
var fill = utils.fill;
var wrapConsoleMethod = _dereq_(2).wrapMethod; var wrapConsoleMethod = _dereq_(3).wrapMethod;
var dsnKeys = 'source protocol user pass host port path'.split(' '), var dsnKeys = 'source protocol user pass host port path'.split(' '),
dsnPattern = /^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w\.-]+)(?::(\d+))?(\/.*)/; dsnPattern = /^(?:(\w+):)?\/\/(?:(\w+)(:\w+)?@)?([\w\.-]+)(?::(\d+))?(\/.*)/;
@ -93,6 +124,7 @@ function now() {
return +new Date(); return +new Date();
} }
// First, check for JSON support // First, check for JSON support
// If there is no JSON, we no-op the core features of Raven // If there is no JSON, we no-op the core features of Raven
// since JSON is required to encode the payload // since JSON is required to encode the payload
@ -115,7 +147,8 @@ function Raven() {
crossOrigin: 'anonymous', crossOrigin: 'anonymous',
collectWindowErrors: true, collectWindowErrors: true,
maxMessageLength: 0, maxMessageLength: 0,
stackTraceLimit: 50 stackTraceLimit: 50,
autoBreadcrumbs: true
}; };
this._ignoreOnError = 0; this._ignoreOnError = 0;
this._isRavenInstalled = false; this._isRavenInstalled = false;
@ -128,7 +161,6 @@ function Raven() {
this._startTime = now(); this._startTime = now();
this._wrappedBuiltIns = []; this._wrappedBuiltIns = [];
this._breadcrumbs = []; this._breadcrumbs = [];
this._breadcrumbLimit = 20;
this._lastCapturedEvent = null; this._lastCapturedEvent = null;
this._keypressTimeout; this._keypressTimeout;
this._location = window.location; this._location = window.location;
@ -150,7 +182,7 @@ Raven.prototype = {
// webpack (using a build step causes webpack #1617). Grunt verifies that // webpack (using a build step causes webpack #1617). Grunt verifies that
// this value matches package.json during build. // this value matches package.json during build.
// See: https://github.com/getsentry/raven-js/issues/465 // See: https://github.com/getsentry/raven-js/issues/465
VERSION: '3.0.4', VERSION: '3.5.1',
debug: false, debug: false,
@ -200,6 +232,22 @@ Raven.prototype = {
this._globalOptions.ignoreUrls = this._globalOptions.ignoreUrls.length ? joinRegExp(this._globalOptions.ignoreUrls) : false; 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.whitelistUrls = this._globalOptions.whitelistUrls.length ? joinRegExp(this._globalOptions.whitelistUrls) : false;
this._globalOptions.includePaths = joinRegExp(this._globalOptions.includePaths); this._globalOptions.includePaths = joinRegExp(this._globalOptions.includePaths);
this._globalOptions.maxBreadcrumbs = Math.max(0, Math.min(this._globalOptions.maxBreadcrumbs || 100, 100)); // default and hard limit is 100
var autoBreadcrumbDefaults = {
xhr: true,
console: true,
dom: true,
location: true
};
var autoBreadcrumbs = this._globalOptions.autoBreadcrumbs;
if ({}.toString.call(autoBreadcrumbs) === '[object Object]') {
autoBreadcrumbs = objectMerge(autoBreadcrumbDefaults, autoBreadcrumbs);
} else if (autoBreadcrumbs !== false) {
autoBreadcrumbs = autoBreadcrumbDefaults;
}
this._globalOptions.autoBreadcrumbs = autoBreadcrumbs;
this._globalKey = uri.user; this._globalKey = uri.user;
this._globalSecret = uri.pass && uri.pass.substr(1); this._globalSecret = uri.pass && uri.pass.substr(1);
@ -210,14 +258,6 @@ Raven.prototype = {
this._globalEndpoint = this._globalServer + this._globalEndpoint = this._globalServer +
'/' + path + 'api/' + this._globalProject + '/store/'; '/' + path + 'api/' + this._globalProject + '/store/';
if (this._globalOptions.fetchContext) {
TraceKit.remoteFetching = true;
}
if (this._globalOptions.linesOfContext) {
TraceKit.linesOfContext = this._globalOptions.linesOfContext;
}
TraceKit.collectWindowErrors = !!this._globalOptions.collectWindowErrors; TraceKit.collectWindowErrors = !!this._globalOptions.collectWindowErrors;
// return for chaining // return for chaining
@ -238,7 +278,9 @@ Raven.prototype = {
TraceKit.report.subscribe(function () { TraceKit.report.subscribe(function () {
self._handleOnErrorStackInfo.apply(self, arguments); self._handleOnErrorStackInfo.apply(self, arguments);
}); });
this._wrapBuiltIns(); this._instrumentTryCatch();
if (self._globalOptions.autoBreadcrumbs)
this._instrumentBreadcrumbs();
// Install all of the plugins // Install all of the plugins
this._drainPlugins(); this._drainPlugins();
@ -429,7 +471,7 @@ Raven.prototype = {
}, obj); }, obj);
this._breadcrumbs.push(crumb); this._breadcrumbs.push(crumb);
if (this._breadcrumbs.length > this._breadcrumbLimit) { if (this._breadcrumbs.length > this._globalOptions.maxBreadcrumbs) {
this._breadcrumbs.shift(); this._breadcrumbs.shift();
} }
}, },
@ -500,7 +542,20 @@ Raven.prototype = {
*/ */
getContext: function() { getContext: function() {
// lol javascript // lol javascript
return JSON.parse(JSON.stringify(this._globalContext)); return JSON.parse(stringify(this._globalContext));
},
/*
* Set environment of application
*
* @param {string} environment Typically something like 'production'.
* @return {Raven}
*/
setEnvironment: function(environment) {
this._globalOptions.environment = environment;
return this;
}, },
/* /*
@ -523,7 +578,10 @@ Raven.prototype = {
* @return {Raven} * @return {Raven}
*/ */
setDataCallback: function(callback) { setDataCallback: function(callback) {
this._globalOptions.dataCallback = callback; var original = this._globalOptions.dataCallback;
this._globalOptions.dataCallback = isFunction(callback)
? function (data) { return callback(data, original); }
: callback;
return this; return this;
}, },
@ -536,7 +594,10 @@ Raven.prototype = {
* @return {Raven} * @return {Raven}
*/ */
setShouldSendCallback: function(callback) { setShouldSendCallback: function(callback) {
this._globalOptions.shouldSendCallback = callback; var original = this._globalOptions.shouldSendCallback;
this._globalOptions.shouldSendCallback = isFunction(callback)
? function (data) { return callback(data, original); }
: callback;
return this; return this;
}, },
@ -794,16 +855,10 @@ Raven.prototype = {
/** /**
* Install any queued plugins * Install any queued plugins
*/ */
_wrapBuiltIns: function() { _instrumentTryCatch: function() {
var self = this; var self = this;
function fill(obj, name, replacement, noUndo) { var wrappedBuiltIns = self._wrappedBuiltIns;
var orig = obj[name];
obj[name] = replacement(orig);
if (!noUndo) {
self._wrappedBuiltIns.push([obj, name, orig]);
}
}
function wrapTimeFn(orig) { function wrapTimeFn(orig) {
return function (fn, t) { // preserve arity return function (fn, t) { // preserve arity
@ -829,6 +884,8 @@ Raven.prototype = {
}; };
} }
var autoBreadcrumbs = this._globalOptions.autoBreadcrumbs;
function wrapEventTarget(global) { function wrapEventTarget(global) {
var proto = window[global] && window[global].prototype; var proto = window[global] && window[global].prototype;
if (proto && proto.hasOwnProperty && proto.hasOwnProperty('addEventListener')) { if (proto && proto.hasOwnProperty && proto.hasOwnProperty('addEventListener')) {
@ -842,10 +899,10 @@ Raven.prototype = {
// can sometimes get 'Permission denied to access property "handle Event' // can sometimes get 'Permission denied to access property "handle Event'
} }
// More breadcrumb DOM capture ... done here and not in `_instrumentBreadcrumbs`
// TODO: more than just click // so that we don't have more than one wrapper function
var before; var before;
if (global === 'EventTarget' || global === 'Node') { if (autoBreadcrumbs && autoBreadcrumbs.dom && (global === 'EventTarget' || global === 'Node')) {
if (evtName === 'click'){ if (evtName === 'click'){
before = self._breadcrumbEventHandler(evtName); before = self._breadcrumbEventHandler(evtName);
} else if (evtName === 'keypress') { } else if (evtName === 'keypress') {
@ -854,39 +911,24 @@ Raven.prototype = {
} }
return orig.call(this, evtName, self.wrap(fn, undefined, before), capture, secure); return orig.call(this, evtName, self.wrap(fn, undefined, before), capture, secure);
}; };
}); }, wrappedBuiltIns);
fill(proto, 'removeEventListener', function (orig) { fill(proto, 'removeEventListener', function (orig) {
return function (evt, fn, capture, secure) { return function (evt, fn, capture, secure) {
fn = fn && (fn.__raven_wrapper__ ? fn.__raven_wrapper__ : fn); fn = fn && (fn.__raven_wrapper__ ? fn.__raven_wrapper__ : fn);
return orig.call(this, evt, fn, capture, secure); return orig.call(this, evt, fn, capture, secure);
}; };
}); }, wrappedBuiltIns);
} }
} }
function wrapProp(prop, xhr) { fill(window, 'setTimeout', wrapTimeFn, wrappedBuiltIns);
if (prop in xhr && isFunction(xhr[prop])) { fill(window, 'setInterval', wrapTimeFn, wrappedBuiltIns);
fill(xhr, prop, function (orig) {
return self.wrap(orig);
}, true /* noUndo */); // don't track filled methods on XHR instances
}
}
fill(window, 'setTimeout', wrapTimeFn);
fill(window, 'setInterval', wrapTimeFn);
if (window.requestAnimationFrame) { if (window.requestAnimationFrame) {
fill(window, 'requestAnimationFrame', function (orig) { fill(window, 'requestAnimationFrame', function (orig) {
return function (cb) { return function (cb) {
return orig(self.wrap(cb)); return orig(self.wrap(cb));
}; };
}); }, wrappedBuiltIns);
}
// Capture breadcrubms from any click that is unhandled / bubbled up all the way
// to the document. Do this before we instrument addEventListener.
if (this._hasDocument) {
document.addEventListener('click', self._breadcrumbEventHandler('click'));
document.addEventListener('keypress', self._keypressEventHandler());
} }
// event targets borrowed from bugsnag-js: // event targets borrowed from bugsnag-js:
@ -896,7 +938,41 @@ Raven.prototype = {
wrapEventTarget(eventTargets[i]); wrapEventTarget(eventTargets[i]);
} }
if ('XMLHttpRequest' in window) { var $ = window.jQuery || window.$;
if ($ && $.fn && $.fn.ready) {
fill($.fn, 'ready', function (orig) {
return function (fn) {
return orig.call(this, self.wrap(fn));
};
}, wrappedBuiltIns);
}
},
/**
* Instrument browser built-ins w/ breadcrumb capturing
* - XMLHttpRequests
* - DOM interactions (click/typing)
* - window.location changes
* - console
*
* Can be disabled or individually configured via the `autoBreadcrumbs` config option
*/
_instrumentBreadcrumbs: function () {
var self = this;
var autoBreadcrumbs = this._globalOptions.autoBreadcrumbs;
var wrappedBuiltIns = self._wrappedBuiltIns;
function wrapProp(prop, xhr) {
if (prop in xhr && isFunction(xhr[prop])) {
fill(xhr, prop, function (orig) {
return self.wrap(orig);
}); // intentionally don't track filled methods on XHR instances
}
}
if (autoBreadcrumbs.xhr && 'XMLHttpRequest' in window) {
var xhrproto = XMLHttpRequest.prototype; var xhrproto = XMLHttpRequest.prototype;
fill(xhrproto, 'open', function(origOpen) { fill(xhrproto, 'open', function(origOpen) {
return function (method, url) { // preserve arity return function (method, url) { // preserve arity
@ -912,7 +988,7 @@ Raven.prototype = {
return origOpen.apply(this, arguments); return origOpen.apply(this, arguments);
}; };
}); }, wrappedBuiltIns);
fill(xhrproto, 'send', function(origSend) { fill(xhrproto, 'send', function(origSend) {
return function (data) { // preserve arity return function (data) { // preserve arity
@ -941,7 +1017,7 @@ Raven.prototype = {
if ('onreadystatechange' in xhr && isFunction(xhr.onreadystatechange)) { if ('onreadystatechange' in xhr && isFunction(xhr.onreadystatechange)) {
fill(xhr, 'onreadystatechange', function (orig) { fill(xhr, 'onreadystatechange', function (orig) {
return self.wrap(orig, undefined, onreadystatechangeHandler); return self.wrap(orig, undefined, onreadystatechangeHandler);
}, true /* noUndo */); } /* intentionally don't track this instrumentation */);
} else { } else {
// if onreadystatechange wasn't actually set by the page on this xhr, we // if onreadystatechange wasn't actually set by the page on this xhr, we
// are free to set our own and capture the breadcrumb // are free to set our own and capture the breadcrumb
@ -950,11 +1026,31 @@ Raven.prototype = {
return origSend.apply(this, arguments); return origSend.apply(this, arguments);
}; };
}); }, wrappedBuiltIns);
}
// Capture breadcrumbs from any click that is unhandled / bubbled up all the way
// to the document. Do this before we instrument addEventListener.
if (autoBreadcrumbs.dom && this._hasDocument) {
if (document.addEventListener) {
document.addEventListener('click', self._breadcrumbEventHandler('click'), false);
document.addEventListener('keypress', self._keypressEventHandler(), false);
}
else {
// IE8 Compatibility
document.attachEvent('onclick', self._breadcrumbEventHandler('click'));
document.attachEvent('onkeypress', self._keypressEventHandler());
}
} }
// record navigation (URL) changes // record navigation (URL) changes
if ('history' in window && history.pushState) { // NOTE: in Chrome App environment, touching history.pushState, *even inside
// a try/catch block*, will cause Chrome to output an error to console.error
// borrowed from: https://github.com/angular/angular.js/pull/13945/files
var chrome = window.chrome;
var isChromePackagedApp = chrome && chrome.app && chrome.app.runtime;
var hasPushState = !isChromePackagedApp && window.history && history.pushState;
if (autoBreadcrumbs.location && hasPushState) {
// TODO: remove onpopstate handler on uninstall() // TODO: remove onpopstate handler on uninstall()
var oldOnPopState = window.onpopstate; var oldOnPopState = window.onpopstate;
window.onpopstate = function () { window.onpopstate = function () {
@ -980,9 +1076,10 @@ Raven.prototype = {
return origPushState.apply(this, arguments); return origPushState.apply(this, arguments);
}; };
}); }, wrappedBuiltIns);
} }
if (autoBreadcrumbs.console && 'console' in window && console.log) {
// console // console
var consoleMethodCallback = function (msg, data) { var consoleMethodCallback = function (msg, data) {
self.captureBreadcrumb({ self.captureBreadcrumb({
@ -992,20 +1089,11 @@ Raven.prototype = {
}); });
}; };
if ('console' in window && console.log) {
each(['debug', 'info', 'warn', 'error', 'log'], function (_, level) { each(['debug', 'info', 'warn', 'error', 'log'], function (_, level) {
wrapConsoleMethod(console, level, consoleMethodCallback); wrapConsoleMethod(console, level, consoleMethodCallback);
}); });
} }
var $ = window.jQuery || window.$;
if ($ && $.fn && $.fn.ready) {
fill($.fn, 'ready', function (orig) {
return function (fn) {
return orig.call(this, self.wrap(fn));
};
});
}
}, },
_restoreBuiltIns: function () { _restoreBuiltIns: function () {
@ -1106,13 +1194,7 @@ Raven.prototype = {
lineno: frame.line, lineno: frame.line,
colno: frame.column, colno: frame.column,
'function': frame.func || '?' 'function': frame.func || '?'
}, context = this._extractContextFromFrame(frame), 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 normalized.in_app = !( // determine if an exception came from outside of our app
// first we check the global includePaths list. // first we check the global includePaths list.
@ -1126,55 +1208,12 @@ Raven.prototype = {
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;
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;
}
}
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
];
}
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) { _processException: function(type, message, fileurl, lineno, frames, options) {
var stacktrace, fullMessage; var stacktrace;
if (!!this._globalOptions.ignoreErrors.test && this._globalOptions.ignoreErrors.test(message)) return; if (!!this._globalOptions.ignoreErrors.test && this._globalOptions.ignoreErrors.test(message)) return;
message += ''; message += '';
message = truncate(message, this._globalOptions.maxMessageLength);
fullMessage = (type ? type + ': ' : '') + message;
fullMessage = truncate(fullMessage, this._globalOptions.maxMessageLength);
if (frames && frames.length) { if (frames && frames.length) {
fileurl = frames[0].filename || fileurl; fileurl = frames[0].filename || fileurl;
@ -1204,8 +1243,7 @@ Raven.prototype = {
stacktrace: stacktrace stacktrace: stacktrace
}] }]
}, },
culprit: fileurl, culprit: fileurl
message: fullMessage
}, options); }, options);
// Fire away! // Fire away!
@ -1216,7 +1254,9 @@ Raven.prototype = {
// For now, we only want to truncate the two different messages // For now, we only want to truncate the two different messages
// but this could/should be expanded to just trim everything // but this could/should be expanded to just trim everything
var max = this._globalOptions.maxMessageLength; var max = this._globalOptions.maxMessageLength;
if (data.message) {
data.message = truncate(data.message, max); data.message = truncate(data.message, max);
}
if (data.exception) { if (data.exception) {
var exception = data.exception.values[0]; var exception = data.exception.values[0];
exception.value = truncate(exception.value, max); exception.value = truncate(exception.value, max);
@ -1247,8 +1287,6 @@ Raven.prototype = {
_send: function(data) { _send: function(data) {
var self = this;
var globalOptions = this._globalOptions; var globalOptions = this._globalOptions;
var baseData = { var baseData = {
@ -1286,6 +1324,9 @@ Raven.prototype = {
data.user = this._globalContext.user; data.user = this._globalContext.user;
} }
// Include the environment if it's defined in globalOptions
if (globalOptions.environment) data.environment = globalOptions.environment;
// Include the release if it's defined in globalOptions // Include the release if it's defined in globalOptions
if (globalOptions.release) data.release = globalOptions.release; if (globalOptions.release) data.release = globalOptions.release;
@ -1306,6 +1347,13 @@ Raven.prototype = {
return; return;
} }
this._sendProcessedPayload(data);
},
_sendProcessedPayload: function(data, callback) {
var self = this;
var globalOptions = this._globalOptions;
// Send along an event_id if not explicitly passed. // Send along an event_id if not explicitly passed.
// This event_id can be used to reference the error within Sentry itself. // This event_id can be used to reference the error within Sentry itself.
// Set lastEventId after we know the error should actually be sent // Set lastEventId after we know the error should actually be sent
@ -1327,10 +1375,14 @@ Raven.prototype = {
auth.sentry_secret = this._globalSecret; auth.sentry_secret = this._globalSecret;
} }
var exception = data.exception && data.exception.values[0];
this.captureBreadcrumb({ this.captureBreadcrumb({
category: 'sentry', category: 'sentry',
message: data.message, message: exception
event_id: data.event_id ? (exception.type ? exception.type + ': ' : '') + exception.value
: data.message,
event_id: data.event_id,
level: data.level || 'error' // presume error unless specified
}); });
var url = this._globalEndpoint; var url = this._globalEndpoint;
@ -1344,12 +1396,15 @@ Raven.prototype = {
data: data, data: data,
src: url src: url
}); });
callback && callback();
}, },
onError: function failure() { onError: function failure(error) {
self._triggerEvent('failure', { self._triggerEvent('failure', {
data: data, data: data,
src: url src: url
}); });
error = error || new Error('Raven send failed (no additional details provided)');
callback && callback(error);
} }
}); });
}, },
@ -1371,7 +1426,7 @@ Raven.prototype = {
opts.onSuccess(); opts.onSuccess();
} }
} else if (opts.onError) { } else if (opts.onError) {
opts.onError(); opts.onError(new Error('Sentry error code: ' + request.status));
} }
} }
@ -1395,14 +1450,7 @@ Raven.prototype = {
// NOTE: auth is intentionally sent as part of query string (NOT as custom // NOTE: auth is intentionally sent as part of query string (NOT as custom
// HTTP header) so as to avoid preflight CORS requests // HTTP header) so as to avoid preflight CORS requests
request.open('POST', url + '?' + urlencode(opts.auth)); request.open('POST', url + '?' + urlencode(opts.auth));
request.send(JSON.stringify(opts.data)); request.send(stringify(opts.data));
},
// 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');
}, },
_logDebug: function(level) { _logDebug: function(level) {
@ -1431,7 +1479,7 @@ Raven.prototype.setReleaseContext = Raven.prototype.setRelease;
module.exports = Raven; module.exports = Raven;
},{"1":1,"2":2,"5":5,"6":6}],4:[function(_dereq_,module,exports){ },{"1":1,"2":2,"3":3,"6":6,"7":7}],5:[function(_dereq_,module,exports){
/** /**
* Enforces a single instance of the Raven client, and the * Enforces a single instance of the Raven client, and the
* main entry point for Raven. If you are a consumer of the * main entry point for Raven. If you are a consumer of the
@ -1440,7 +1488,7 @@ module.exports = Raven;
'use strict'; 'use strict';
var RavenConstructor = _dereq_(3); var RavenConstructor = _dereq_(4);
var _Raven = window.Raven; var _Raven = window.Raven;
@ -1461,7 +1509,7 @@ Raven.afterLoad();
module.exports = Raven; module.exports = Raven;
},{"3":3}],5:[function(_dereq_,module,exports){ },{"4":4}],6:[function(_dereq_,module,exports){
/*eslint no-extra-parens:0*/ /*eslint no-extra-parens:0*/
'use strict'; 'use strict';
@ -1700,6 +1748,21 @@ function htmlElementAsString(elem) {
return out.join(''); return out.join('');
} }
/**
* Polyfill a method
* @param obj object e.g. `document`
* @param name method name present on object e.g. `addEventListener`
* @param replacement replacement function
* @param track {optional} record instrumentation to an array
*/
function fill(obj, name, replacement, track) {
var orig = obj[name];
obj[name] = replacement(orig);
if (track) {
track.push([obj, name, orig]);
}
}
module.exports = { module.exports = {
isUndefined: isUndefined, isUndefined: isUndefined,
isFunction: isFunction, isFunction: isFunction,
@ -1716,13 +1779,14 @@ module.exports = {
uuid4: uuid4, uuid4: uuid4,
htmlTreeAsString: htmlTreeAsString, htmlTreeAsString: htmlTreeAsString,
htmlElementAsString: htmlElementAsString, htmlElementAsString: htmlElementAsString,
parseUrl: parseUrl parseUrl: parseUrl,
fill: fill
}; };
},{}],6:[function(_dereq_,module,exports){ },{}],7:[function(_dereq_,module,exports){
'use strict'; 'use strict';
var utils = _dereq_(5); var utils = _dereq_(6);
var hasKey = utils.hasKey; var hasKey = utils.hasKey;
var isString = utils.isString; var isString = utils.isString;
@ -1734,10 +1798,7 @@ var isUndefined = utils.isUndefined;
*/ */
var TraceKit = { var TraceKit = {
remoteFetching: false,
collectWindowErrors: true, collectWindowErrors: true,
// 3 lines before, the offending line, 3 lines after
linesOfContext: 7,
debug: false debug: false
}; };
@ -1897,7 +1958,6 @@ TraceKit.report = (function reportModuleWrapper() {
} }
location.func = UNKNOWN_FUNCTION; location.func = UNKNOWN_FUNCTION;
location.context = null;
stack = { stack = {
'name': name, 'name': name,
@ -2000,7 +2060,6 @@ TraceKit.report = (function reportModuleWrapper() {
* s.stack[i].args - arguments passed to the function, if known * s.stack[i].args - arguments passed to the function, if known
* s.stack[i].line - line number, if known * s.stack[i].line - line number, if known
* s.stack[i].column - column number, if known * s.stack[i].column - column number, if known
* s.stack[i].context - an array of source code lines; the middle element corresponds to the correct line#
* *
* Supports: * Supports:
* - Firefox: full stack trace with line numbers and unreliable column * - Firefox: full stack trace with line numbers and unreliable column
@ -2109,7 +2168,7 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() {
var chrome = /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|<anonymous>).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i, var chrome = /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|<anonymous>).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i,
gecko = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|\[native).*?)(?::(\d+))?(?::(\d+))?\s*$/i, gecko = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|\[native).*?)(?::(\d+))?(?::(\d+))?\s*$/i,
winjs = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:ms-appx|https?|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i, winjs = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i,
lines = ex.stack.split('\n'), lines = ex.stack.split('\n'),
stack = [], stack = [],
parts, parts,
@ -2150,10 +2209,6 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() {
element.func = UNKNOWN_FUNCTION; element.func = UNKNOWN_FUNCTION;
} }
if (element.line) {
element.context = null;
}
stack.push(element); stack.push(element);
} }
@ -2219,7 +2274,6 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() {
if (!element.func && element.line) { if (!element.func && element.line) {
element.func = UNKNOWN_FUNCTION; element.func = UNKNOWN_FUNCTION;
} }
element.context = [lines[line + 1]];
stack.push(element); stack.push(element);
} }
@ -2307,7 +2361,6 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() {
if (!item.func) { if (!item.func) {
item.func = UNKNOWN_FUNCTION; item.func = UNKNOWN_FUNCTION;
} }
item.context = [lines[line + 1]];
stack.push(item); stack.push(item);
} }
@ -2357,7 +2410,6 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() {
return false; // already in stack trace return false; // already in stack trace
} else if (!stackInfo.stack[0].line && stackInfo.stack[0].func === initial.func) { } else if (!stackInfo.stack[0].line && stackInfo.stack[0].func === initial.func) {
stackInfo.stack[0].line = initial.line; stackInfo.stack[0].line = initial.line;
stackInfo.stack[0].context = initial.context;
return false; return false;
} }
} }
@ -2512,5 +2564,5 @@ TraceKit.computeStackTrace = (function computeStackTraceWrapper() {
module.exports = TraceKit; module.exports = TraceKit;
},{"5":5}]},{},[4])(4) },{"6":6}]},{},[5])(5)
}); });
Loading…
Cancel
Save