Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error using chrome.tabs.sendMessage with await #208

Open
lolaraghvendra opened this issue May 11, 2024 · 1 comment
Open

Error using chrome.tabs.sendMessage with await #208

lolaraghvendra opened this issue May 11, 2024 · 1 comment

Comments

@lolaraghvendra
Copy link

I used to add await directly while calling the chrome.tabs.sendMessage and it used to work great:

const data = await chrome.tabs.sendMessage(tab.id, {
  type: 'get_data',
});

for some unknown reasons it stopped working that way months ago and i desperately need to use it asynchronously!

the solution i tried looks something like this:

i created a utility function in another file utils.js to use it anywhere i needed

export function sendMessageToContent(tabId, request) {
  return new Promise((resolve, reject) => {
    chrome.tabs.sendMessage(tabId, request, (response) => {
      console.log("response recieved from content script -- ", response, "at ",new Date().toISOString());
      if (chrome.runtime.lastError) {
        console.log("error caught in response of content script -- ", chrome.runtime.lastError);
        reject(chrome.runtime.lastError);
      } else {
        resolve(response);
      }
    });
  });
}

and i use it in my popup.jsx like this:

 // I call this function on a button click
 const getCanonicalLink = async () => {
    const [tab] = await chrome.tabs.query({
      currentWindow: true,
      active: true,
    });

    console.log("message sent for tab id -- ",tab.id)
    const response = await sendMessageToContent(tab.id,{
      type:'get_data'
    });

    console.log("response -- ",response);
    return data;
  };

The thing is i am not getting a response from the sendMessageToContent and instead the chrome.runtime.lastError is set in callback of this function and this following error is caught:
image

as per the code in my content script (mentioned below) the code is executed successfully and there is no error in the logic but there is always a delay between the last log of the content script and the callback in the sendMessageToContent
content script log:
image

popup log:
image

afaik, the call back is called only when the sendResponse is called, so i guess the flow is OK. but why am i getting the response in this callback as undefined
This is how far i have reached and i cant understand what shall i do exactly to make it work asynchronously!

BTW, here is the code in content script:

chrome.runtime.onMessage.addListener(async function (request, sender, sendResponse) {
  console.log('request', request);
  console.log('sender', sender);

  if (request.type === 'get_data') {
    try {
      
      const ab = await fetch(window.location.href);
      let parser1 = new DOMParser();

      // Parse the text
      let html = parser1.parseFromString(await ab.text(), 'text/html');
      console.log(html);
      // let canonical = html.querySelector('link[rel=canonical]')['href'];
      let canonical = html.querySelector('link[rel=canonical]');
      console.log('canonical', canonical);

      if (canonical) {
        canonical = html.querySelector('link[rel=canonical]')['href'];
        let username = document.querySelectorAll('#channel-handle')[1].textContent;

        console.log('canonical', canonical);
        // return canonical;
        sendResponse({
          canonicalLink: canonical,
          redirectedUrl: ab.url,
          username,
        });
      } else {
        sendResponse({
          canonicalLink: null,
          redirectedUrl: ab.url,
          username: window.location.href.split('@')[1],
        });
      }
      console.log("request processed!!",new Date().toISOString());
    } catch (error) {
      console.log("error caught in content script -- ",error);
      sendResponse({error})
    }
    // return true;
  }
}
@Toumash
Copy link

Toumash commented Jun 1, 2024

Isnt this the same as https://stackoverflow.com/a/20077854/3711660?
Meaning you need to return true and then use async code like await fetch(). Wrap async code in a function call it (with void operator, not await like soe void runAsyncCode();return true; )and return true

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants