Search code examples
javascriptgoogle-chrome-extensionchromiumchrome-extension-manifest-v3browser-extension

How to pass error from extension service worker to content script?


I have a browser extension in which my content script requests information from a background script (service worker). Usually, this works fine, but in some cases the information cannot be retrieved by the background script. In that case, I want the background script to send the content script an error containing some information about the nature of the problem.

However, when sending an error via the sendResponse function, the content script receives only an empty object. Why does this happen and how can I send an error from the background script to the content script?

content-script.js:

const showResult = (res) => {
  console.log('Received the following response from background script:\n', res);
};

chrome.runtime.sendMessage('send me a user!').then((res) => showResult(res));
chrome.runtime.sendMessage('send me a user!').then((res) => showResult(res));

background-script.js:

const responses = [
  new Error('something bad happened'),
  { name: 'John Doe', age: 38 }
];

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  const response = responses.pop()
  console.log('Going to send the following response:\n', response);
  sendResponse(response);
});

manifest.json:

{
  "manifest_version": 3,
  "name": "A test",
  "version": "0.0.1",

  "content_scripts": [
    {
      "matches": ["https://www.google.com/*"],
      "js": ["content-script.js"]
    }
  ],

  "background": {
    "type": "module",
    "service_worker": "background-script.js"
  }
}

Console output from background-script.js:

Going to send the following response:
 {name: 'John Doe', age: 38}
-------------------------------------------------------
Going to send the following response:
 Error: something bad happened
    at background-script.js:2:3

Console output from content-script.js:

Received the following response from background script:
 {name: 'John Doe', age: 38}
-------------------------------------------------------
Received the following response from background script:
 {}

Browser: Chromium Version 115.0.5790.170 (Official Build)


Solution

  • The source of your empty object is likely because chrome.runtime.sendMessage requires message to be JSON serializable, and new Error() is not.

    To directly pass the error information, you'll want to do something like:

    const error = new Error('something bad happened');
    const serializedError = JSON.stringify({
      message: error.message,
      name: error.name,
      stack: error.stack
    });