Bug 1317447: Provide better error messages when browser is removed before we can send replies. r=aswan
authorKris Maglione <maglione.k@gmail.com>
Fri, 18 Nov 2016 13:06:00 -0800
changeset 323504 d8dc1806bb827ab612513ea27918b361ae584d99
parent 323503 aa98f9492ef7a1e9de2b21cf2d3b164b7a20955f
child 323505 9df2b4f740d723d4b8380f64cf0ba6ef19947630
push id30978
push usercbook@mozilla.com
push dateMon, 21 Nov 2016 14:44:46 +0000
treeherdermozilla-central@0534254e9a40 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaswan
bugs1317447
milestone53.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 1317447: Provide better error messages when browser is removed before we can send replies. r=aswan MozReview-Commit-ID: 19Qmi220qOt
toolkit/components/extensions/ExtensionParent.jsm
toolkit/components/extensions/ExtensionUtils.jsm
--- a/toolkit/components/extensions/ExtensionParent.jsm
+++ b/toolkit/components/extensions/ExtensionParent.jsm
@@ -456,61 +456,63 @@ ParentAPIManager = {
       context.unload();
       this.proxyContexts.delete(childId);
     }
   },
 
   call(data, target) {
     let context = this.getContextById(data.childId);
     if (context.parentMessageManager !== target.messageManager) {
-      Cu.reportError("WebExtension warning: Message manager unexpectedly changed");
+      throw new Error("Got message on unexpected message manager");
     }
 
+    let reply = result => {
+      if (!context.parentMessageManager) {
+        Cu.reportError("Cannot send function call result: other side closed connection");
+        return;
+      }
+
+      context.parentMessageManager.sendAsyncMessage(
+        "API:CallResult",
+        Object.assign({
+          childId: data.childId,
+          callId: data.callId,
+        }, result));
+    };
+
     try {
       let args = Cu.cloneInto(data.args, context.sandbox);
       let result = findPathInObject(context.apiObj, data.path)(...args);
 
       if (data.callId) {
         result = result || Promise.resolve();
 
         result.then(result => {
           result = result instanceof SpreadArgs ? [...result] : [result];
 
-          context.parentMessageManager.sendAsyncMessage("API:CallResult", {
-            childId: data.childId,
-            callId: data.callId,
-            result,
-          });
+          reply({result});
         }, error => {
           error = context.normalizeError(error);
-          context.parentMessageManager.sendAsyncMessage("API:CallResult", {
-            childId: data.childId,
-            callId: data.callId,
-            error: {message: error.message},
-          });
+          reply({error: {message: error.message}});
         });
       }
     } catch (e) {
       if (data.callId) {
         let error = context.normalizeError(e);
-        context.parentMessageManager.sendAsyncMessage("API:CallResult", {
-          childId: data.childId,
-          callId: data.callId,
-          error: {message: error.message},
-        });
+        reply({error: {message: error.message}});
       } else {
         Cu.reportError(e);
       }
     }
   },
 
   addListener(data, target) {
     let context = this.getContextById(data.childId);
     if (context.parentMessageManager !== target.messageManager) {
-      Cu.reportError("WebExtension warning: Message manager unexpectedly changed");
+      throw new Error("Got message on unexpected message manager");
     }
 
     let {childId} = data;
 
     function listener(...listenerArgs) {
       return context.sendMessage(
         context.parentMessageManager,
         "API:RunListener",
--- a/toolkit/components/extensions/ExtensionUtils.jsm
+++ b/toolkit/components/extensions/ExtensionUtils.jsm
@@ -1079,17 +1079,21 @@ class MessageManagerProxy {
    * Sends a message on the proxied message manager.
    *
    * @param {array} args
    *        Arguments to be passed verbatim to the underlying
    *        sendAsyncMessage method.
    * @returns {undefined}
    */
   sendAsyncMessage(...args) {
-    return this.messageManager.sendAsyncMessage(...args);
+    if (this.messageManager) {
+      return this.messageManager.sendAsyncMessage(...args);
+    }
+    /* globals uneval */
+    Cu.reportError(`Cannot send message: Other side disconnected: ${uneval(args)}`);
   }
 
   /**
    * Adds a message listener to the current message manager, and
    * transfers it to the new message manager after a docShell swap.
    *
    * @param {string} message
    *        The name of the message to listen for.