Bug 1498410 - Part 2 - Export Screenshots 35.0.0 (upgrade Raven to 3.27.0); r=ianbicking
☠☠ backed out by b2cd2ffe4ec8 ☠ ☠
authorJared Hirsch <ohai@6a68.net>
Mon, 15 Oct 2018 20:11:30 +0000
changeset 489683 909a38c04700e32793a82e92a1b35aa182cae276
parent 489682 fb1c936feb43f2571bd35d3fd904ec40ef3148ac
child 489684 426257ad4b83e3cffc628f76ae8bd55c2fa4fbaf
push id247
push userfmarier@mozilla.com
push dateSat, 27 Oct 2018 01:06:44 +0000
reviewersianbicking
bugs1498410
milestone64.0a1
Bug 1498410 - Part 2 - Export Screenshots 35.0.0 (upgrade Raven to 3.27.0); r=ianbicking MozReview-Commit-ID: 711GJNJtNYn Differential Revision: https://phabricator.services.mozilla.com/D8504
browser/extensions/screenshots/build/raven.js
browser/extensions/screenshots/webextension/build/raven.js
rename from browser/extensions/screenshots/webextension/build/raven.js
rename to browser/extensions/screenshots/build/raven.js
--- a/browser/extensions/screenshots/webextension/build/raven.js
+++ b/browser/extensions/screenshots/build/raven.js
@@ -1,17 +1,17 @@
-/*! Raven.js 3.25.2 (30b6d4e) | github.com/getsentry/raven-js */
+/*! Raven.js 3.27.0 (200cffcc) | github.com/getsentry/raven-js */
 
 /*
  * Includes TraceKit
  * https://github.com/getsentry/TraceKit
  *
- * Copyright 2018 Matt Robenolt and other contributors
- * Released under the BSD license
- * https://github.com/getsentry/raven-js/blob/master/LICENSE
+ * Copyright (c) 2018 Sentry (https://sentry.io) and individual contributors.
+ * All rights reserved.
+ * https://github.com/getsentry/sentry-javascript/blob/master/packages/raven-js/LICENSE
  *
  */
 
 (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 RavenConfigError(message) {
   this.name = 'RavenConfigError';
   this.message = message;
 }
@@ -112,21 +112,17 @@ var dsnKeys = 'source protocol user pass
 function now() {
   return +new Date();
 }
 
 // This is to be defensive in environments where window does not exist (see https://github.com/getsentry/raven-js/pull/785)
 var _window =
   typeof window !== 'undefined'
     ? window
-    : typeof global !== 'undefined'
-      ? global
-      : typeof self !== 'undefined'
-        ? self
-        : {};
+    : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
 var _document = _window.document;
 var _navigator = _window.navigator;
 
 function keepOriginalCallback(original, callback) {
   return isFunction(callback)
     ? function(data) {
         return callback(data, original);
       }
@@ -165,17 +161,16 @@ function Raven() {
     stackTraceLimit: 50,
     autoBreadcrumbs: true,
     instrument: true,
     sampleRate: 1,
     sanitizeKeys: []
   };
   this._fetchDefaults = {
     method: 'POST',
-    keepalive: true,
     // Despite all stars in the sky saying that Edge supports old draft syntax, aka 'never', 'always', 'origin' and 'default
     // https://caniuse.com/#feat=referrer-policy
     // It doesn't. And it throw exception instead of ignoring this parameter...
     // REF: https://github.com/getsentry/raven-js/issues/1233
     referrerPolicy: supportsReferrerPolicy() ? 'origin' : ''
   };
   this._ignoreOnError = 0;
   this._isRavenInstalled = false;
@@ -206,17 +201,17 @@ function Raven() {
  * @this {Raven}
  */
 
 Raven.prototype = {
   // Hardcode version string so that raven source can be loaded directly via
   // webpack (using a build step causes webpack #1617). Grunt verifies that
   // this value matches package.json during build.
   //   See: https://github.com/getsentry/raven-js/issues/465
-  VERSION: '3.25.2',
+  VERSION: '3.27.0',
 
   debug: false,
 
   TraceKit: TraceKit, // alias to TraceKit
 
   /*
      * Configure Raven with a DSN and extra options
      *
@@ -372,28 +367,28 @@ Raven.prototype = {
      * @param {object} options A specific set of options for this context [optional]
      * @param {function} func The callback to be immediately executed within the context
      * @param {array} args An array of arguments to be called with the callback [optional]
      */
   context: function(options, func, args) {
     if (isFunction(options)) {
       args = func || [];
       func = options;
-      options = undefined;
+      options = {};
     }
 
     return this.wrap(options, func).apply(this, args);
   },
 
   /*
      * Wrap code within a context and returns back a new function to be executed
      *
      * @param {object} options A specific set of options for this context [optional]
      * @param {function} func The function to be wrapped in a new context
-     * @param {function} func A function to call before the try/catch wrapper [optional, private]
+     * @param {function} _before A function to call before the try/catch wrapper [optional, private]
      * @return {function} The newly wrapped functions with a context
      */
   wrap: function(options, func, _before) {
     var self = this;
     // 1 argument has been passed, and it's not a function
     // so just return it
     if (isUndefined(func) && !isFunction(options)) {
       return options;
@@ -496,18 +491,19 @@ Raven.prototype = {
    * @param {PromiseRejectionEvent} event An object containing
    *   promise: the Promise that was rejected
    *   reason: the value with which the Promise was rejected
    * @return void
    */
   _promiseRejectionHandler: function(event) {
     this._logDebug('debug', 'Raven caught unhandled promise rejection:', event);
     this.captureException(event.reason, {
-      extra: {
-        unhandledPromiseRejection: true
+      mechanism: {
+        type: 'onunhandledrejection',
+        handled: false
       }
     });
   },
 
   /**
    * Installs the global promise rejection handler.
    *
    * @return {raven}
@@ -682,17 +678,19 @@ Raven.prototype = {
 
     if (
       !!this._globalOptions.whitelistUrls.test &&
       !this._globalOptions.whitelistUrls.test(fileurl)
     ) {
       return;
     }
 
-    if (this._globalOptions.stacktrace || (options && options.stacktrace)) {
+    // Always attempt to get stacktrace if message is empty.
+    // It's the only way to provide any helpful information to the user.
+    if (this._globalOptions.stacktrace || options.stacktrace || data.message === '') {
       // fingerprint on msg, not stack trace (legacy behavior, could be revisited)
       data.fingerprint = data.fingerprint == null ? msg : data.fingerprint;
 
       options = objectMerge(
         {
           trimHeadFrames: 0
         },
         options
@@ -941,44 +939,50 @@ Raven.prototype = {
   },
 
   showReportDialog: function(options) {
     if (
       !_document // doesn't work without a document (React native)
     )
       return;
 
-    options = options || {};
-
-    var lastEventId = options.eventId || this.lastEventId();
-    if (!lastEventId) {
+    options = objectMerge(
+      {
+        eventId: this.lastEventId(),
+        dsn: this._dsn,
+        user: this._globalContext.user || {}
+      },
+      options
+    );
+
+    if (!options.eventId) {
       throw new RavenConfigError('Missing eventId');
     }
 
-    var dsn = options.dsn || this._dsn;
-    if (!dsn) {
+    if (!options.dsn) {
       throw new RavenConfigError('Missing DSN');
     }
 
     var encode = encodeURIComponent;
-    var qs = '';
-    qs += '?eventId=' + encode(lastEventId);
-    qs += '&dsn=' + encode(dsn);
-
-    var user = options.user || this._globalContext.user;
-    if (user) {
-      if (user.name) qs += '&name=' + encode(user.name);
-      if (user.email) qs += '&email=' + encode(user.email);
+    var encodedOptions = [];
+
+    for (var key in options) {
+      if (key === 'user') {
+        var user = options.user;
+        if (user.name) encodedOptions.push('name=' + encode(user.name));
+        if (user.email) encodedOptions.push('email=' + encode(user.email));
+      } else {
+        encodedOptions.push(encode(key) + '=' + encode(options[key]));
+      }
     }
-
-    var globalServer = this._getGlobalServer(this._parseDSN(dsn));
+    var globalServer = this._getGlobalServer(this._parseDSN(options.dsn));
 
     var script = _document.createElement('script');
     script.async = true;
-    script.src = globalServer + '/api/embed/error-page/' + qs;
+    script.src = globalServer + '/api/embed/error-page/?' + encodedOptions.join('&');
     (_document.head || _document.body).appendChild(script);
   },
 
   /**** Private functions ****/
   _ignoreNextOnError: function() {
     var self = this;
     this._ignoreOnError += 1;
     setTimeout(function() {
@@ -1174,17 +1178,25 @@ Raven.prototype = {
         // Make a copy of the arguments to prevent deoptimization
         // https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments
         var args = new Array(arguments.length);
         for (var i = 0; i < args.length; ++i) {
           args[i] = arguments[i];
         }
         var originalCallback = args[0];
         if (isFunction(originalCallback)) {
-          args[0] = self.wrap(originalCallback);
+          args[0] = self.wrap(
+            {
+              mechanism: {
+                type: 'instrument',
+                data: {function: orig.name || '<anonymous>'}
+              }
+            },
+            originalCallback
+          );
         }
 
         // 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 {
@@ -1201,17 +1213,29 @@ Raven.prototype = {
         fill(
           proto,
           'addEventListener',
           function(orig) {
             return function(evtName, fn, capture, secure) {
               // preserve arity
               try {
                 if (fn && fn.handleEvent) {
-                  fn.handleEvent = self.wrap(fn.handleEvent);
+                  fn.handleEvent = self.wrap(
+                    {
+                      mechanism: {
+                        type: 'instrument',
+                        data: {
+                          target: global,
+                          function: 'handleEvent',
+                          handler: (fn && fn.name) || '<anonymous>'
+                        }
+                      }
+                    },
+                    fn.handleEvent
+                  );
                 }
               } catch (err) {
                 // can sometimes get 'Permission denied to access property "handle Event'
               }
 
               // More breadcrumb DOM capture ... done here and not in `_instrumentBreadcrumbs`
               // so that we don't have more than one wrapper function
               var before, clickHandler, keypressHandler;
@@ -1241,17 +1265,30 @@ Raven.prototype = {
                   }
                   if (eventType === 'click') return clickHandler(evt);
                   else if (eventType === 'keypress') return keypressHandler(evt);
                 };
               }
               return orig.call(
                 this,
                 evtName,
-                self.wrap(fn, undefined, before),
+                self.wrap(
+                  {
+                    mechanism: {
+                      type: 'instrument',
+                      data: {
+                        target: global,
+                        function: 'addEventListener',
+                        handler: (fn && fn.name) || '<anonymous>'
+                      }
+                    }
+                  },
+                  fn,
+                  before
+                ),
                 capture,
                 secure
               );
             };
           },
           wrappedBuiltIns
         );
         fill(
@@ -1275,17 +1312,30 @@ Raven.prototype = {
     fill(_window, 'setTimeout', wrapTimeFn, wrappedBuiltIns);
     fill(_window, 'setInterval', wrapTimeFn, wrappedBuiltIns);
     if (_window.requestAnimationFrame) {
       fill(
         _window,
         'requestAnimationFrame',
         function(orig) {
           return function(cb) {
-            return orig(self.wrap(cb));
+            return orig(
+              self.wrap(
+                {
+                  mechanism: {
+                    type: 'instrument',
+                    data: {
+                      function: 'requestAnimationFrame',
+                      handler: (orig && orig.name) || '<anonymous>'
+                    }
+                  }
+                },
+                cb
+              )
+            );
           };
         },
         wrappedBuiltIns
       );
     }
 
     // event targets borrowed from bugsnag-js:
     // https://github.com/bugsnag/bugsnag-js/blob/master/src/bugsnag.js#L666
@@ -1338,17 +1388,25 @@ Raven.prototype = {
     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);
+          return self.wrap(
+            {
+              mechanism: {
+                type: 'instrument',
+                data: {function: prop, handler: (orig && orig.name) || '<anonymous>'}
+              }
+            },
+            orig
+          );
         }); // intentionally don't track filled methods on XHR instances
       }
     }
 
     if (autoBreadcrumbs.xhr && 'XMLHttpRequest' in _window) {
       var xhrproto = _window.XMLHttpRequest && _window.XMLHttpRequest.prototype;
       fill(
         xhrproto,
@@ -1403,17 +1461,29 @@ Raven.prototype = {
               wrapProp(props[j], xhr);
             }
 
             if ('onreadystatechange' in xhr && isFunction(xhr.onreadystatechange)) {
               fill(
                 xhr,
                 'onreadystatechange',
                 function(orig) {
-                  return self.wrap(orig, undefined, onreadystatechangeHandler);
+                  return self.wrap(
+                    {
+                      mechanism: {
+                        type: 'instrument',
+                        data: {
+                          function: 'onreadystatechange',
+                          handler: (orig && orig.name) || '<anonymous>'
+                        }
+                      }
+                    },
+                    orig,
+                    onreadystatechangeHandler
+                  );
                 } /* intentionally don't track this instrumentation */
               );
             } else {
               // if onreadystatechange wasn't actually set by the page on this xhr, we
               // are free to set our own and capture the breadcrumb
               xhr.onreadystatechange = onreadystatechangeHandler;
             }
 
@@ -1627,20 +1697,26 @@ Raven.prototype = {
     var globalServer = '//' + uri.host + (uri.port ? ':' + uri.port : '');
 
     if (uri.protocol) {
       globalServer = uri.protocol + ':' + globalServer;
     }
     return globalServer;
   },
 
-  _handleOnErrorStackInfo: function() {
+  _handleOnErrorStackInfo: function(stackInfo, options) {
+    options = options || {};
+    options.mechanism = options.mechanism || {
+      type: 'onerror',
+      handled: false
+    };
+
     // if we are intentionally ignoring errors via onerror, bail out
     if (!this._ignoreOnError) {
-      this._handleStackInfo.apply(this, arguments);
+      this._handleStackInfo(stackInfo, options);
     }
   },
 
   _handleStackInfo: function(stackInfo, options) {
     var frames = this._prepareFrames(stackInfo, options);
 
     this._triggerEvent('handle', {
       stackInfo: stackInfo,
@@ -1767,16 +1843,37 @@ Raven.prototype = {
             }
           ]
         },
         transaction: fileurl
       },
       options
     );
 
+    var ex = data.exception.values[0];
+    if (ex.type == null && ex.value === '') {
+      ex.value = 'Unrecoverable error caught';
+    }
+
+    // Move mechanism from options to exception interface
+    // We do this, as requiring user to pass `{exception:{mechanism:{ ... }}}` would be
+    // too much
+    if (!data.exception.mechanism && data.mechanism) {
+      data.exception.mechanism = data.mechanism;
+      delete data.mechanism;
+    }
+
+    data.exception.mechanism = objectMerge(
+      {
+        type: 'generic',
+        handled: true
+      },
+      data.exception.mechanism || {}
+    );
+
     // Fire away!
     this._send(data);
   },
 
   _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;
@@ -2330,17 +2427,21 @@ module.exports.Client = RavenConstructor
 }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
 },{"3":3}],5:[function(_dereq_,module,exports){
 (function (global){
 var stringify = _dereq_(7);
 
 var _window =
   typeof window !== 'undefined'
     ? window
-    : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
+    : typeof global !== 'undefined'
+      ? global
+      : typeof self !== 'undefined'
+        ? self
+        : {};
 
 function isObject(what) {
   return typeof what === 'object' && what !== null;
 }
 
 // Yanked from https://git.io/vS8DV re-used under CC0
 // with some tiny modifications
 function isError(value) {
@@ -2744,16 +2845,19 @@ function isSameException(ex1, ex2) {
  * Returns true if the two input stack trace interfaces have the same content
  */
 function isSameStacktrace(stack1, stack2) {
   if (isOnlyOneTruthy(stack1, stack2)) return false;
 
   var frames1 = stack1.frames;
   var frames2 = stack2.frames;
 
+  // Exit early if stacktrace is malformed
+  if (frames1 === undefined || frames2 === undefined) return false;
+
   // Exit early if frame count differs
   if (frames1.length !== frames2.length) return false;
 
   // Iterate through every frame; bail out if anything differs
   var a, b;
   for (var i = 0; i < frames1.length; i++) {
     a = frames1[i];
     b = frames2[i];
@@ -3014,21 +3118,22 @@ function getLocationHref() {
   return document.location.href;
 }
 
 function getLocationOrigin() {
   if (typeof document === 'undefined' || document.location == null) return '';
 
   // Oh dear IE10...
   if (!document.location.origin) {
-    document.location.origin =
+    return (
       document.location.protocol +
       '//' +
       document.location.hostname +
-      (document.location.port ? ':' + document.location.port : '');
+      (document.location.port ? ':' + document.location.port : '')
+    );
   }
 
   return document.location.origin;
 }
 
 /**
  * TraceKit.report: cross-browser processing of unhandled exceptions
  *
@@ -4002,9 +4107,9 @@ function md5(string, key, raw) {
     return hexHMACMD5(key, string);
   }
   return rawHMACMD5(key, string);
 }
 
 module.exports = md5;
 
 },{}]},{},[4])(4)
-});
\ No newline at end of file
+});