2

I'm currently working on developing a Chrome extension and have noticed that my extension works fine for several days or longer, but eventually reaches a state where various event listeners seem to stop working. For instance, my extension listens for storage updates coming from its popup and also for an alarm which is triggered every minute, but at some point both these seem to stop working simultaneously. My event listeners are registered synchronously as far as I can tell, and they continue to work for far longer than I would expect if this were not the case.

Further, when the extension reaches this state, I find that when I add test event listeners in the service worker console, these listeners don't appear to trigger properly either.

I have not been able to identify the precise circumstances under which this issue occurs, or replicate it successfully, except by waiting several days with my extension running. The issue does not appear to be associated with any runtime exceptions. If anyone has experienced a similar issue or has any debugging advice I'd greatly appreciate it. At this point, I'm not sure how to continue investigating this issue.

  • Sounds like the known bug in ManifestV3 registration of the service worker. There's no solution, but you can try removing the extension and installing it again. That said, it can be a bug in your code. – wOxxOm Nov 05 '22 at 07:07
  • https://stackoverflow.com/questions/66618136/persistent-service-worker-in-chrome-extension ... the first answer in this thread will be the solution. I've solved this problem in the past by using the code from this response. I found the one that uses ```chrome.runtime.onConnect.addListener(port => {``` worked best. – Jridyard Nov 05 '22 at 17:58

1 Answers1

1

I have struggled with this issue recently and have seen this question posted a number of times with minimal answers or support. I wanted to provide some feedback on what I discovered in my investigation and maybe it could be helpful to you.

Background:

A few months back, we started receiving occasionally complaints from some of the users that the Chrome extension is no longer functioning. Essentially, buttons were not being inserted into their webpage as expected. Users had the ability to login to our system from the extension icon, but it did not trigger the scripts to run in the tab. The only way to resolve the issue was by restarting the browser or the computer.

The extension registers a number of alarms, an onTabUpdate listener, and an onMessage listener, none of which were responding. Even when opening the devtools, I could not do any actions, like sending a message, or even call chrome.runtime.reload(), and no logs appeared.

A couple of key notes:

  1. The issue would appear after a few days of use without issue
  2. Not all users experienced the issue
  3. It happened over multiple versions of the extension

Investigation:

Using chrome://serviceworker-internals, I was able to identify that during normal behavior, the extension would enter a RUNNING status when the alarms triggered or when the tab was changed/opened and after 30 seconds of inactivity, the extension would change to a STOPPED state, but would reenter the RUNNING state when there was an event or message.

Findings:

Since I cannot reproduce the issue on my own, I cannot confirm that this resolves our situation, but it may help you in yours.

I found 2 key things in my code that may help here:

On a logout event from my system, the background script would post a message that the frontend script would be listening for. To send this message, I ran a tabs query on all tabs.

chrome.tabs.query({ status: 'complete' }, (tabs) => {
    tabs.forEach((tab) => {
        chrome.tabs.sendMessage(tab.id, { event: 'logout', data: {} }, () => {});
    });
});
  1. The first issue in my code, is that I never called the sendResponse() (I had just assumed that I didn't need it, so why call it), even though the onMessage had return True. The code was expecting an asynchronous response, but never received it, and would throw an error:
Error: A listener indicated an asynchronous response by returning true, but the message channel closed before a response was received

This error did not seem to have an real effect on the runtime or behaviour of my code, and I couldn't figure it out, so I ignored it.

  1. The second issue seems to have stemmed from the tabs query being on all tabs. In my manifest I limit my extension to only certain websites. This resulted in a second error:
uncaught (in promise) error: could not establish connection. receiving end does not exist.

Both of these errors take time to resolve (the timeout is something like 60 seconds) and during that time, the extension remained in the running state. If the user has many tabs open (like most people usually do), the extension would eventually get stuck in this perpetual running state.

Actions Taken

Here, I am not quite sure what is happening (whether there is or isn't a bug in Chrome), but it seems like after X period of time, the Chrome API listeners stop responding. As the extension never stops and restarts, there is no recovery of the listeners and the background script is forever stuck in this state. The extension icon works without an issue, but the main script is never executed. Only a restart of Chrome or the computer seems to resolve this.

I resolved the 2 issues by calling sendMessage() in any place I have an onMessage listener and by changing the tabs query to <all_urls> which limits the query to the tabs that match the urls in the manifest, which removed the 2 errors. As a result, the extension now seems to have returned to the active/inactive cycle in the background script. On every wake up, the background script runs, reinitializing the alarms, if required, and resetting the listeners.

Hopefully this helps with this scenario. Best of luck!

Yacov
  • 11
  • 2
  • Do you really feel everything is working ? I'm having the same "not reproductible on my side" issue. At some point, the chrome.tabs.onXXX are not triggered anymore. – Alytrem Jun 14 '23 at 20:03