Erros I got when send a message asynchronously
I got some errors related to messaging from a content script to another part of the extension for example a background JavaScript.
These are the errors I got,
- Uncaught (in promise) Error: A listener indicated an asynchronous response by returning true, but the message channel closed before a response was received
- Error sending message: The message port closed before a response was received.
I found I need to understand how to send a message to another part of the browser extension asynchronously.
Then I will be able to know how to solve these problems.
How to send a message in Browser Extension in Manifest V3
I learned this with Chrome Extension API – Message passing
What I found was that,
On the receiving side (the onMessage listener), sendResponse is always used to send a reply. However, on the sending side (where sendMessage is called), you can choose to receive the response in callback or promise.
But you can’t use a promise and a callback in the same call.
This is a way to get a response by using callback.
// Content Script (sending side)
chrome.runtime.sendMessage({ action: "getData" }, (response) => {
console.log("Response received:", response);
});
This is a way to get a response by using promise.
// Content Script (sending side)
(async () => { const response = await chrome.runtime.sendMessage({ action: "getData" }); console.log("Response received:", response); })();
To send a single message, we need to use chrome.runtime.sendMessage() or tabs.sendMessage().
How to receive a message and response in Browser Extension in Manifest V3
If you want to do it asynchronously, you must return a literal true (return true😉 from the event listener. Doing so will keep the message channel open to the other end until sendResponse is called.
This is a sample code for the receiving side that returns value asynchronously.
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action === "getData") {
setTimeout(() => {
sendResponse({ success: true, data: "Delayed Response!" });
}, 1000);
return true; // support asynchronous
}
});
I came across a note stating that the listener function should not be an async function. This is likely because returning a Promise and returning true or false might conflict and cause unexpected behavior.
Leave a comment