0

This is part of a Chrome Extension (MV3).

A helper function in background.js tries to determine the active Chrome tab:

async function getCurrentTab() {
  let queryOptions = { active: true, currentWindow: true };
  let [tab] = await chrome.tabs.query(queryOptions);
  if (chrome.runtime.lastError) {
    console.log(`[getCurrentTab] Error : ${chrome.runtime.lastError.message}.`);
    window.setTimeout(() => getCurrentTab(), 100);
  } else {          
    console.log(`[getCurrentTab] ✅`);
  }
  return tab;
}

When the extension performs an action (i.e. sends a message to contentScript.js), I pass the activeTab as an argument to chrome.tabs.sendMessage:

getCurrentTab().then((activeTab) => {
    if (!isAuthenticated) {
      chrome.tabs.sendMessage(activeTab.id, { name: "unauthenticated" }, function(response) {
        if (chrome.runtime.lastError) {
          console.log(`[background.js] Error from response for "unauthenticated" received : ${chrome.runtime.lastError.message}`);
        } else {          
          console.log(`[background.js] Response for "unauthenticated" received ✅: ${response}`);
        }
      });
      return;
    }

This part (activeTab.id) sometimes (it's ad-hoc) throws this error:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'id')

I haven't been able to identify a pattern in terms of the error, and most time a page refresh will fix it.

Any clues?


EDIT (based on comment from @lawrence-cherone)

I've now changed code to:

async function getCurrentTab() {
  let queryOptions = { active: true, currentWindow: true };
  let [tab] = await chrome.tabs.query(queryOptions);
  if (chrome.runtime.lastError) {
    console.log(`[getCurrentTab] Error : ${chrome.runtime.lastError.message}.`);
    await asyncTimeout(100);
  } else {          
    console.log(`[getCurrentTab] ✅`);
  }
  return tab;
}

const asyncTimeout = (ms) => {
  return new Promise((resolve) => {
    window.setTimeout(() => {
      getCurrentTab(),
      ms
    });
  });
};

Let's see what happens.

ppp
  • 713
  • 1
  • 8
  • 23
  • this part `window.setTimeout(() => getCurrentTab(), 100);` is not going to `return` a promise – Lawrence Cherone Mar 23 '23 at 14:11
  • You're right, though execution never hits that part when it happens. – ppp Mar 23 '23 at 14:30
  • the error comes from using `activeTab.id` when `activeTab` is undefined, from docs `tab` will either be a `tabs.Tab` instance or `undefined` – Lawrence Cherone Mar 23 '23 at 14:35
  • edited the code as per your comment – ppp Mar 23 '23 at 14:42
  • 1
    Your current window is probably devtools, so query() returns an empty tabs array, it's a bug in Chrome. See [this answer](https://stackoverflow.com/a/63886442) for a workaround. Also 1) chrome.runtime.lastError doesn't work with Promise/await (you need to use the standard try/catch), 2) there's no `window` in MV3 service worker so just use `setTimeout` directly. – wOxxOm Mar 23 '23 at 15:45

0 Answers0