fix: sendMessage promise should resolve to undefined when no listeners reply
This commit is contained in:
parent
7ff6e8a1dc
commit
4e1e98add2
|
@ -7,6 +7,7 @@
|
|||
"use strict";
|
||||
|
||||
if (typeof browser === "undefined") {
|
||||
const CHROME_SEND_MESSAGE_CALLBACK_NO_RESPONSE_MESSAGE = "The message port closed before a response was received.";
|
||||
const SEND_RESPONSE_DEPRECATION_WARNING = `
|
||||
Returning a Promise is the preferred way to send a reply from an
|
||||
onMessage/onMessageExternal listener, as the sendResponse will be
|
||||
|
@ -446,7 +447,14 @@ if (typeof browser === "undefined") {
|
|||
|
||||
const wrappedSendMessageCallback = ({reject, resolve}, reply) => {
|
||||
if (chrome.runtime.lastError) {
|
||||
// Detect when none of the listers replied to the sendMessage call and resolve
|
||||
// the promise to undefined as in Firefox.
|
||||
// See https://github.com/mozilla/webextension-polyfill/issues/130
|
||||
if (chrome.runtime.lastError.message === CHROME_SEND_MESSAGE_CALLBACK_NO_RESPONSE_MESSAGE) {
|
||||
resolve();
|
||||
} else {
|
||||
reject(chrome.runtime.lastError);
|
||||
}
|
||||
} else if (reply && reply.__mozWebExtensionPolyfillReject__) {
|
||||
// Convert back the JSON representation of the error into
|
||||
// an Error instance.
|
||||
|
|
|
@ -45,6 +45,9 @@ browser.runtime.onMessage.addListener((msg, sender, sendResponse) => {
|
|||
case "test - sendMessage with listener callback throws":
|
||||
throw new Error("listener throws");
|
||||
|
||||
case "test - sendMessage and no listener answers":
|
||||
return undefined;
|
||||
|
||||
default:
|
||||
return Promise.resolve(
|
||||
`Unxpected message received by the background page: ${JSON.stringify(msg)}\n`);
|
||||
|
@ -52,6 +55,10 @@ browser.runtime.onMessage.addListener((msg, sender, sendResponse) => {
|
|||
});
|
||||
|
||||
browser.runtime.onMessage.addListener((msg, sender, sendResponse) => {
|
||||
if (msg === "test - sendMessage and no listener answers") {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
sendResponse("second listener reply");
|
||||
}, 100);
|
||||
|
|
|
@ -75,3 +75,8 @@ test("sendMessage with listener callback throws", async (t) => {
|
|||
t.equal(err.message, "listener throws", "Got an error with the expected message");
|
||||
}
|
||||
});
|
||||
|
||||
test("sendMessage and no listener answers", async (t) => {
|
||||
const reply = await browser.runtime.sendMessage("test - sendMessage and no listener answers");
|
||||
t.equal(reply, undefined, "Got undefined reply as expected");
|
||||
});
|
||||
|
|
|
@ -238,5 +238,30 @@ describe("browser-polyfill", () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("resolves to undefined when no listeners reply", () => {
|
||||
const fakeChrome = {
|
||||
runtime: {
|
||||
// This error message is defined as CHROME_SEND_MESSAGE_CALLBACK_NO_RESPONSE_MESSAGE
|
||||
// in the polyfill sources and it is used to recognize when Chrome has detected that
|
||||
// none of the listeners replied.
|
||||
lastError: {
|
||||
message: "The message port closed before a response was received.",
|
||||
},
|
||||
sendMessage: sinon.stub(),
|
||||
},
|
||||
};
|
||||
|
||||
fakeChrome.runtime.sendMessage.onFirstCall().callsArgWith(1, [undefined]);
|
||||
|
||||
return setupTestDOMWindow(fakeChrome).then(window => {
|
||||
const promise = window.browser.runtime.sendMessage("some_message");
|
||||
ok(fakeChrome.runtime.sendMessage.calledOnce, "sendMessage has been called once");
|
||||
|
||||
return promise.then(reply => {
|
||||
deepEqual(reply, undefined, "sendMessage promise should be resolved to undefined");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue