New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 859735 link

Starred by 1 user

Issue metadata

Status: Assigned
Owner:
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: ----
Pri: 3
Type: Bug



Sign in to add a comment

Extension sendMessage API documentation for asynchronous responses should be clearer

Project Member Reported by rlyons@google.com, Jul 3

Issue description

Chrome Version       : 67.0.3396.99
OS Version: 10.0

Using the chrome API chrome.runtime.onMessage.addListener to respond to a message chrome.runtime.sendMessage while executing the sendResponse method inside a promise or callback will cause a disconnect.

URLs (if applicable) :
Other browsers tested: Chrome API. 

What steps will reproduce the problem?
1. Setup a chrome.runtime.onMessage.addListener in a background script with a response sent in a callback/promise.
2. Setup a message sender chrome.runtime.sendMessage from a content script with the 'response' method to console.log the response value. 
3. Send a message from the content script and then run chrome.runtime.lasterror

What is the expected result?
The content script stays connected to the backend messaging script until the message is received or the sendResponse message terminates. 


What happens instead of that?
Content script receives a disconnected message. "The message port closed before a response was received."

Please provide any additional information below. Attach a screenshot if
possible.



UserAgentString: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36



 
Cc: rdevlin....@chromium.org lazyboy@chromium.org
Components: Platform>Extensions>API
rlyons@ can you share the code samples you have too? 

This helps to visualize better the issue.
Background Code:

class Message {  
  /** 
   * Stores a message to the chrome synced storage.
   * @param {{id: string, msg: string}} msg is the message object to be stored.
   */
  static store (msg) {
    //...
  }
  
  /** 
   * Retrieves a message from synced storage.
   * @param {string} msg is the case id.
   */
  static retrieve (msg) {
    return new Promise((resolve) => {
      chrome.storage.sync.get(msg, rec => {
        resolve(rec[msg]);
      });
    });
  }
}


/** Creates a runtime listener for requests. */
chrome.runtime.onMessage.addListener(
  (request, sender, sendResponse) => {
  if(request.messageStore) {
    Message.store(request.messageStore);
  }

  if(request.messageRetrieve) {
     Message.retrieve(request.messageRetrieve).then(rec => {
       sendResponse({msg: rec});
       return true;
     });
  }
});


Content Script:

chrome.runtime.sendMessage({messageRetrieve:this.caseid}, msg => {
  console.log(chrome.runtime.lastError);
  console.log(msg);
});
I figured it out, I needed to move the 'return true' outside the asynchronous method. 
Cc: lucmult@chromium.org
Yes, you need "return true" as per the documentation:
https://developer.chrome.com/extensions/runtime#event-onMessage
BTW, this problem is brought up regularly on stackoverflow.com so apparently the documentation needs an update.
I'd say the messaging article should have a more prominent async case description and a demo code:
https://developer.chrome.com/extensions/messaging
Cc: krajshree@chromium.org
Labels: Needs-Feedback Triaged-ET Needs-Triage-M67
rlyons@google.com - Thanks for filing the issue...!!

Could you please provide a sample test file/url to test the issue from TE-end as the code at comment #3 is not of much help to us. This will help us in triaging the issue further. The code at comment #3 is not of much help.

Thanks...!!
Components: -Platform>Extensions>API Platform>Extensions>Documentation
Labels: -Needs-Feedback -Needs-Triage-M67
Owner: rdevlin....@chromium.org
Status: Assigned (was: Unconfirmed)
Summary: Extension sendMessage API documentation for asynchronous responses should be clearer (was: Chrome sendMessage API closes port before asynchronous message is sent. )
@6 I agree - this has definitely come up a lot.

We already document it in the messaging article [1], but it's not visible enough.  Maybe the demo code like you suggest, and perhaps also alluding to it in the runtime.sendMessage documentation - I'll see if we can add those soon.

Updating the bug description and components.

[1] We say:
In the above example, sendResponse was called synchronously. If you want to asynchronously use sendResponse, add return true; to the onMessage event handler.

...

Note: The sendResponse callback is only valid if used synchronously, or if the event handler returns true to indicate that it will respond asynchronously. The sendMessage function's callback will be invoked automatically if no handlers return true or if the sendResponse callback is garbage-collected.

Sign in to add a comment