Bug 1317447: Provide better error messages when browser is removed before we can send replies. r?aswan
MozReview-Commit-ID: 19Qmi220qOt
--- 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.