chrome.tabs.sendMessage throw error

6,808 views
Skip to first unread message

Aleksej Todorovic

unread,
Mar 7, 2022, 9:29:07 AM3/7/22
to Chromium Extensions
Hello all,

I've noticed that my extension as of Chrome 99 throws an error if something goes wrong with chrome.tabs.sendMessage(tabId, message) (eg. listener in tab not set/ready, or no content script, etc).

I've checked in the earliest version, and it looks like chrome.runtime.lastError was silently processed if no callback set.

The message that I see is: "Uncaught (in promise) Error: Could not establish connection. Receiving end does not exist.”

Is this on purpose or not? 

wOxxOm

unread,
Mar 8, 2022, 12:54:03 PM3/8/22
to Chromium Extensions, aleksej....@gmail.com

The reason is that sendMessage is now promisified internally, so we can `await` it, but the byproduct is that when we don't specify a callback ourselves, it is added internally anyway in order for the call to return a Promise, which means that since we don't call sendResponse in onMessage, the API will think that it was us who made a mistake of using a callback and not providing a response, and report it as such.

Two workarounds for extensions:

1. Always call sendResponse() inside chrome.runtime.onMessage.

// sender
chrome.runtime.sendMessage('test');

// receiver
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
doSomethingWithoutResponding(msg);
sendResponse();
});

2. Suppress this specific error.
Also patch the API's inherent lack of a callstack prior to the call (a bug in itself BTW).

// sender
sendMessage('foo');
sendMessage('foo').then(res => whatever(res));
await sendMessage('foo');

function sendMessage(msg, options) {
const err1 = new Error('Callstack before sendMessage:');
return new Promise((resolve, reject) => {
chrome.runtime.sendMessage(undefined, msg, options, res => {
let err2 = chrome.runtime.lastError;
if (!err2 || err2.message.startsWith('The message port closed before')) {
resolve(res);
} else {
err2 = new Error(err2.message);
err2.stack += err1.stack.replace(/^Error:\s*/, '');
reject(err2);
}
});
});
}

Alexey Makhrov

unread,
Apr 14, 2022, 10:54:05 PM4/14/22
to Chromium Extensions, wOxxOm, aleksej....@gmail.com
@w0xx0m - it looks like you code snippet addresses a different error ("The message port closed before ...").

The OP asks about "Could not establish connection. Receiving end does not exist.".
I also started observing this one recently. I'm getting it even though I'm using an empty "sendResponse()" call as per your first workaround

wOxxOm

unread,
Apr 15, 2022, 2:09:57 AM4/15/22
to Chromium Extensions, ale...@crunchbase.com, wOxxOm, aleksej....@gmail.com
Report it on https://crbug.com.

Jackie Han

unread,
Aug 16, 2022, 8:37:13 AM8/16/22
to Alexey Makhrov, Chromium Extensions, wOxxOm, aleksej....@gmail.com
To suppress "Could not establish connection. Receiving end does not exist." error in MV3, I would like to write like this:

// I know there is most likely no extension pages listening for messages
chrome.runtime.sendMessage(msg, () => chrome.runtime.lastError);

--
You received this message because you are subscribed to the Google Groups "Chromium Extensions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-extens...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/chromium-extensions/65815acb-372c-4663-ae30-343556af4847n%40chromium.org.
Reply all
Reply to author
Forward
0 new messages