2

This is a persistent error I encounter in my Chrome Extension, when I send a message from the background script to the content script.

Weirdly enough, the error happens only under SOME conditions -- for example, if I try to send a message after an onUpdated event listener is triggered, I almost always receive that error. The only workaround I've found is to introduce an arbitrary wait of 3-5 seconds, only after which the message gets reliably sent.

Even weirder I do NOT see the error when the message is sent via an onActivated event listener -- even though basically all the rest of the code is identical aside from the event listener that triggers it.

If I had to guess, it's probably something to do with the fact that the webpage is still loading, the content script for whatever reason isn't available for be receiving messages -- and when you try to send a message to it, it doesn't work.

I tried another workaround where I checked the status of the active tab, and looked for only when the check.status === "complete", but that weirdly didn't work, even when the webpage was clearly loaded. I could loop over it 100 times and it would just say it's in a persistent state of loading.

Has anyone found a reliable method to actually prevent this error from occurring in their Chrome Extensions?

Pertinent code:

BACKGROUND SCRIPT:

chrome.tabs.onUpdated.addListener(function(tabId, change, tab) {
  if (tab.active && change.url) {

      UpdatedTabURL = change.url;
      UpdatedURLTabID = tabId;

      if (typeof PreviousURL !== 'undefined') {
        if (UpdatedTabURL.indexOf(PreviousURL) != -1) {
          return; // this functionally aborts the rest of the code if they're on the same URL. The timer thus doesn't auto-stop and keeps running.
        } // this is specifically to keep the timer running if they're clicking links on and within the same URL website (e.g. browsing around on Reddit)
      }

      for (let i = 0; i < AllURLsToAvoid.length; i++) {
        if (UpdatedTabURL.indexOf(AllURLsToAvoid[i]) != -1) {

          PreviousURL = AllURLsToAvoid[i];

          chrome.windows.onFocusChanged.addListener(function(windowId) {
            if (windowId === chrome.windows.WINDOW_ID_NONE) { // If the user minimized the current browser window, it removes the timer
                chrome.tabs.sendMessage(tabId, {greeting: "Remove Timer"}, function() { 
                })
            }
          });

          chrome.tabs.onActivated.addListener(function(activeInfo) {
            if (activeInfo.tabId !== UpdatedURLTabID) { // if the user switches to another tab, it removes the timer
              chrome.tabs.sendMessage(UpdatedURLTabID, {greeting: "Remove Timer"}, function() { 
              })
            }
          });

          setTimeout(function() { // arbitrarily waits 5 seconds. why? because without this, the receiving end doesn't exist. this waits for it to load. a shitty, suboptimal but functional solution.
            chrome.tabs.sendMessage(tabId, {greeting: "Start Timer"}, function() {
            })
          }, 3000);
        }
      }
    }
});

CONTENT SCRIPT:

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  console.log("Message received:", request);
  if (request.greeting === "Start Timer") {
    sendResponse({farewell: "Timer Started"});
    RemoveTimer();
    StopTimer();
    AddStickyTimer();
    RunTimer();
  }
  if (request.greeting === "Remove Timer") {
    sendResponse({farewell: "Timer Removed"});
    // alert("TIMER REMOVED");
    RemoveTimer();
    StopTimer();
  }
});
king_anton
  • 167
  • 8

0 Answers0