How to prevent chrome extension to run on chrome://

Absolute JS beginner here, please be gentle and pardon my ignorance.

In the background service_worker (background.js) of a Chrome extension I’m trying to build (manifest_version: 3) I use the chrome.action API to control the toolbar icon’s behaviour.

chrome.action.onClicked.addListener(async function (tab) {  
    chrome.scripting.executeScript({
        target: {tabId: tab.id},
        files: ['iconClicked.js']
    });
});

Now when a user clicks the icon whilst being on chrome://extensions, this produces an error:

Uncaught (in promise) Error: Cannot access a chrome:// URL

What can I do to prevent my script to run on chrome:// URLs?

I tried wrapping it in a condition checking the current URL:

if (window.location.href.includes("urls/where/i/want/my/script/to/run") == true) {
    chrome.action.onClicked.addListener(async function (tab) {
        chrome.scripting.executeScript({
            target: {tabId: tab.id},
            files: ['iconClicked.js']
        });
    });
};

But, alas, apparently on chrome:// “window” is not defined:

ReferenceError: window is not defined

How else can I effectively prevent my extension from throwing errors on chrome:// (ideally w/out using jQuery or any other libraries)?

Any hints are greatly appreciated!

Answer

The background script runs as a service worker so it has no relation to location of a web page.

Since executeScript returns a Promise by default so you can catch it to ignore the error:

chrome.action.onClicked.addListener(async tab => {
  await chrome.scripting.executeScript({
    target: {tabId: tab.id},
    files: ['iconClicked.js'],
  }).catch(() => {});
});

Or wrap in try with await:

chrome.action.onClicked.addListener(async tab => {
  try {
    const results = await chrome.scripting.executeScript({
      target: {tabId: tab.id},
      files: ['iconClicked.js'],
    });
    // console.log(results);
  } catch (e) {
    // ignoring the error
  }
});

And for the sake of completeness, ManifestV3 can also be used with callbacks:

chrome.action.onClicked.addListener(tab => {
  chrome.scripting.executeScript({
    target: {tabId: tab.id},
    files: ['iconClicked.js'],
  }, () => chrome.runtime.lastError); // ignoring the error
});