Bug 1437258 - Added exception handling to output webRequest blocking error to debugging console. r=mixedpuppy
☠☠ backed out by 035d5b058729 ☠ ☠
authortossj <tossj@outlook.com>
Mon, 22 Oct 2018 09:36:42 -0400
changeset 508262 51b417f1d2c3ef81f200ef37041864980b962df8
parent 508261 94ef0a404e408ff3cf2b66f3de6aa9605d9a5a25
child 508263 6c17ac872bdfa23edf836b45246eca9201430d6f
push id1905
push userffxbld-merge
push dateMon, 21 Jan 2019 12:33:13 +0000
treeherdermozilla-release@c2fca1944d8c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmixedpuppy
bugs1437258
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1437258 - Added exception handling to output webRequest blocking error to debugging console. r=mixedpuppy
toolkit/components/extensions/ExtensionChild.jsm
toolkit/components/extensions/ExtensionParent.jsm
toolkit/components/extensions/parent/ext-webRequest.js
--- a/toolkit/components/extensions/ExtensionChild.jsm
+++ b/toolkit/components/extensions/ExtensionChild.jsm
@@ -41,16 +41,17 @@ XPCOMUtils.defineLazyGetter(
 XPCOMUtils.defineLazyPreferenceGetter(this, "gTimingEnabled",
                                       "extensions.webextensions.enablePerformanceCounters",
                                       false);
 ChromeUtils.import("resource://gre/modules/ExtensionCommon.jsm");
 ChromeUtils.import("resource://gre/modules/ExtensionUtils.jsm");
 
 const {
   DefaultMap,
+  ExtensionError,
   LimitedSet,
   getMessageManager,
   getUniqueId,
   getWinUtils,
 } = ExtensionUtils;
 
 const {
   EventEmitter,
@@ -928,16 +929,17 @@ class ChildAPIManager {
     this.localApis = localAPICan.root;
     this.apiCan = localAPICan;
     this.schema = this.apiCan.apiManager.schema;
 
     this.id = `${context.extension.id}.${context.contextId}`;
 
     MessageChannel.addListener(messageManager, "API:RunListener", this);
     messageManager.addMessageListener("API:CallResult", this);
+    messageManager.addMessageListener("API:AddListenerResult", this);
 
     this.messageFilterStrict = {childId: this.id};
 
     this.listeners = new DefaultMap(() => ({
       ids: new Map(),
       listeners: new Map(),
       removedIds: new LimitedSet(10),
     }));
@@ -1010,16 +1012,25 @@ class ChildAPIManager {
           deferred.reject(data.error);
         } else {
           let result = data.result.deserialize(this.context.cloneScope);
 
           deferred.resolve(new NoCloneSpreadArgs(result));
         }
         this.callPromises.delete(data.callId);
         break;
+
+      case "API:AddListenerResult":
+        if ("error" in data) {
+          let listenerMap = this.listeners.get(data.path);
+          listenerMap.ids.delete(data.listenerId);
+
+          Promise.reject(new ExtensionError(data.error.message));
+        }
+        break;
     }
   }
 
   /**
    * Call a function in the parent process and ignores its return value.
    *
    * @param {string} path The full name of the method, e.g. "tabs.create".
    * @param {Array} args The parameters for the function.
@@ -1081,16 +1092,17 @@ class ChildAPIManager {
       removeListener: (listener) => impl.removeListener(listener),
       hasListener: (listener) => impl.hasListener(listener),
     };
   }
 
   close() {
     this.messageManager.sendAsyncMessage("API:CloseProxyContext", {childId: this.id});
     this.messageManager.removeMessageListener("API:CallResult", this);
+    this.messageManager.removeMessageListener("API:AddListenerResult", this);
     MessageChannel.removeListener(this.messageManager, "API:RunListener", this);
 
     if (this.updatePermissions) {
       this.context.extension.off("add-permissions", this.updatePermissions);
       this.context.extension.off("remove-permissions", this.updatePermissions);
     }
   }
 
--- a/toolkit/components/extensions/ExtensionParent.jsm
+++ b/toolkit/components/extensions/ExtensionParent.jsm
@@ -976,16 +976,33 @@ ParentAPIManager = {
     if (context.parentMessageManager !== target.messageManager) {
       throw new Error("Got message on unexpected message manager");
     }
 
     let {childId} = data;
     let handlingUserInput = false;
     let lowPriority = data.path.startsWith("webRequest.");
 
+    let reply = result => {
+      if (!context.parentMessageManager) {
+        Services.console.logStringMessage("Cannot send function call " +
+        "result: other side closed connection " +
+        `(call data: ${uneval({path: data.path, args: data.args})})`);
+        return;
+      }
+
+      context.parentMessageManager.sendAsyncMessage(
+        "API:AddListenerResult",
+        Object.assign({
+          childId: data.childId,
+          listenerId: data.listenerId,
+          path: data.path,
+        }, result));
+    };
+
     function listener(...listenerArgs) {
       return context.sendMessage(
         context.parentMessageManager,
         "API:RunListener",
         {
           childId,
           handlingUserInput,
           listenerId: data.listenerId,
@@ -1016,17 +1033,24 @@ ParentAPIManager = {
       let remove = () => { listenerPromises.delete(promise); };
       promise.then(remove, remove);
     }
 
     let handler = await promise;
     if (handler.setUserInput) {
       handlingUserInput = true;
     }
-    handler.addListener(listener, ...args);
+
+    try {
+      handler.addListener(listener, ...args);
+    } catch (e) {
+      context.listenerProxies.delete(data.listenerId);
+      const error = context.normalizeError(e);
+      reply({error: {message: error.message}});
+    }
   },
 
   async removeListener(data) {
     let context = this.getContextById(data.childId);
     let listener = context.listenerProxies.get(data.listenerId);
 
     let handler = await context.apiCan.asyncFindAPIPath(data.path);
     handler.removeListener(listener);
--- a/toolkit/components/extensions/parent/ext-webRequest.js
+++ b/toolkit/components/extensions/parent/ext-webRequest.js
@@ -57,18 +57,18 @@ function registerEvent(extension, eventN
   }
 
   let blockingAllowed = extension.hasPermission("webRequestBlocking");
 
   let info2 = [];
   if (info) {
     for (let desc of info) {
       if (desc == "blocking" && !blockingAllowed) {
-        Cu.reportError("Using webRequest.addListener with the blocking option " +
-                       "requires the 'webRequestBlocking' permission.");
+        throw new ExtensionError("Using webRequest.addListener with the " +
+          "blocking option requires the 'webRequestBlocking' permission.");
       } else {
         info2.push(desc);
       }
     }
   }
 
   let listenerDetails = {
     addonId: extension.id,