Bug 1317447: Provide better error messages when browser is removed before we can send replies. r=aswan, a=jcristau
authorKris Maglione <maglione.k@gmail.com>
Fri, 18 Nov 2016 13:06:00 -0800
changeset 352620 84bb1123f7774f00d63e01735894fcdfae07930d
parent 352619 c7b8df18b1b3e616f244d28c91c1c0b38da8cdd1
child 352621 5cac2e6569d00933d7bf9046cbf9f2a57203ab52
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaswan, jcristau
bugs1317447
milestone52.0a2
Bug 1317447: Provide better error messages when browser is removed before we can send replies. r=aswan, a=jcristau 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
@@ -447,61 +447,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.