Bug 1006102 - Filter out console errors with non-extension sourceName from the addon debugger webconsole. draft
authorLuca Greco <lgreco@mozilla.com>
Mon, 24 Apr 2017 13:51:10 +0200
changeset 568804 ad1ec31b741367c1ebc6475011b69c1802033c70
parent 568802 14c90dad4b0158ad6172ec831360847a22d27e8b
child 568805 b4353b5dcac51197eb5e388579e735532a695d04
push id55987
push userluca.greco@alcacoop.it
push dateWed, 26 Apr 2017 16:09:42 +0000
bugs1006102
milestone55.0a1
Bug 1006102 - Filter out console errors with non-extension sourceName from the addon debugger webconsole. MozReview-Commit-ID: DKTfywF6fsc
devtools/server/actors/utils/webconsole-listeners.js
devtools/server/actors/webconsole.js
devtools/server/actors/webextension.js
--- a/devtools/server/actors/utils/webconsole-listeners.js
+++ b/devtools/server/actors/utils/webconsole-listeners.js
@@ -25,19 +25,20 @@ XPCOMUtils.defineLazyServiceGetter(this,
  * @param nsIDOMWindow [window]
  *        Optional - the window object for which we are created. This is used
  *        for filtering out messages that belong to other windows.
  * @param object listener
  *        The listener object must have one method:
  *        - onConsoleServiceMessage(). This method is invoked with one argument,
  *        the nsIConsoleMessage, whenever a relevant message is received.
  */
-function ConsoleServiceListener(window, listener) {
+function ConsoleServiceListener(window, listener, {customFilterFn} = {}) {
   this.window = window;
   this.listener = listener;
+  this.customFilterFn = customFilterFn;
 }
 exports.ConsoleServiceListener = ConsoleServiceListener;
 
 ConsoleServiceListener.prototype =
 {
   QueryInterface: XPCOMUtils.generateQI([Ci.nsIConsoleListener]),
 
   /**
@@ -80,16 +81,22 @@ ConsoleServiceListener.prototype =
       }
 
       let errorWindow = Services.wm.getOuterWindowWithId(message.outerWindowID);
       if (!errorWindow || !isWindowIncluded(this.window, errorWindow)) {
         return;
       }
     }
 
+    if (typeof this.customFilterFn === "function") {
+      if (!this.customFilterFn(message)) {
+        return;
+      }
+    }
+
     this.listener.onConsoleServiceMessage(message);
   },
 
   /**
    * Check if the given message category is allowed to be tracked or not.
    * We ignore chrome-originating errors as we only care about content.
    *
    * @param string category
@@ -133,16 +140,20 @@ ConsoleServiceListener.prototype =
     // if !this.window, we're in a browser console. Still need to filter
     // private messages.
     if (!this.window) {
       return errors.filter((error) => {
         if (error instanceof Ci.nsIScriptError) {
           if (!includePrivate && error.isFromPrivateWindow) {
             return false;
           }
+
+          if (typeof this.customFilterFn === "function") {
+            return this.customFilterFn(error);
+          }
         }
 
         return true;
       });
     }
 
     let ids = WebConsoleUtils.getInnerWindowIDsForFrames(this.window);
 
--- a/devtools/server/actors/webconsole.js
+++ b/devtools/server/actors/webconsole.js
@@ -574,17 +574,18 @@ WebConsoleActor.prototype =
       switch (listener) {
         case "PageError":
           // Workers don't support this message type yet
           if (isWorker) {
             break;
           }
           if (!this.consoleServiceListener) {
             this.consoleServiceListener =
-              new ConsoleServiceListener(window, this);
+              new ConsoleServiceListener(window, this,
+                                         this.parentActor.consoleServiceListenerOptions);
             this.consoleServiceListener.init();
           }
           startedListeners.push(listener);
           break;
         case "ConsoleAPI":
           if (!this.consoleAPIListener) {
             // Create the consoleAPIListener (and apply the filtering options defined
             // in the parent actor).
--- a/devtools/server/actors/webextension.js
+++ b/devtools/server/actors/webextension.js
@@ -67,16 +67,35 @@ function WebExtensionChildActor(conn, ch
   this._chromeGlobal.addMessageListener("debug:webext_parent_exit", this._onParentExit);
 
   // Set the consoleAPIListener filtering options
   // (retrieved and used in the related webconsole child actor).
   this.consoleAPIListenerOptions = {
     addonId: this.id,
   };
 
+  this.consoleServiceListenerOptions = {
+    customFilterFn: (message) => {
+      if (message instanceof Ci.nsIScriptError) {
+        // Allow message not tied to any source
+        // (used for messages like changing the webconsole console).
+        if (!message.sourceName) {
+          return true;
+        }
+
+        // Allow errors from any of the sources listed in the debugger panel.
+        if (this._allowSource({url: message.sourceName})) {
+          return true;
+        }
+      }
+
+      return false;
+    },
+  };
+
   this.aps = Cc["@mozilla.org/addons/policy-service;1"]
                .getService(Ci.nsIAddonPolicyService);
 
   // This creates a Debugger instance for debugging all the add-on globals.
   this.makeDebugger = makeDebugger.bind(null, {
     findDebuggees: dbg => {
       return dbg.findAllGlobals().filter(this._shouldAddNewGlobalAsDebuggee);
     },