Multiple chrome.runtime.onMessage-Listeners - disconnected port error

Viewed 3152

I´m working on a chrome-extension which uses the indexedDB-Wrapper Dexie, several jQuery-Libraries and syncfusions eGrid to display and modify the database. I know this question was asked several times before, but now I discovered some weird behaviour.

My Setup:

  • background-script
  • content-script (injected into a website)
  • index.html (for displaying the Grid)
  • manifest.json

When I´m reloading my extension everything is fine. I´m injecting a scrollable list of names with my content-script. This also works when I´m reloading the tab. But when I opened the index.html before (popup.html in the official documentation) the sendResponse from background-script stops working after some time. Reloading the tab would not help then. I was searching for hours, found a lot of similiar cases and some entrys on googles bugtracker where they claimed this problem was already fixed. I also know that I have to use return true if I have async funtions like with indexedDB.

So to give you some more information, I will list my shortened scripts.

Content-Script

chrome.runtime.sendMessage({greeting: 'getNames'},function(response){
    $('.names-container').append(response.farewell);
});
chrome.runtime.sendMessage({greeting: 'getData'+name},function(name){
    chrome.runtime.sendMessage({greeting: 'delete'},function(response){
        console.log(response.farewell);
    });
    chrome.runtime.sendMessage({greeting: 'set'}, function(response) {
        console.log(response.farewell);
    });
});

Background-Script

chrome.runtime.onMessage.addListener(function(message,sender,sendResponse){
  if(message.greeting == 'getNames'){
    // Get array of names from idb and send it back
    idb.opendb().then(function(a){
      sendResponse(a);
    });
    return true;
  } else if(message.greeting.indexOf('getData') >= 0){
    // get more information for selected name
    idb.opendb().then(function(a){
      sendResponse(a);
    });
    return true;
  } else if(message.greeting == 'delete'){
    // further processing to delete some stuff
    idb.opendb().then(function(a){
      sendResponse(a);
    });
    return true;
  } else if(message.greeting == 'set'){
    // synchronous function
    // do something ...
    return false;
  } else {
    // Do something
  }
  //return true;
});

funtion indexhtml(){
  chrome.runtime.sendMessage(
    "notifications",
    function (response) {
      console.log(response);
    }
  );
}

Index.html

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse){
  if(request == 'notifications'){
    notifications();
  }

  sendResponse("Message received from background-page for "+request);
});

Manifest

{
    "manifest_version": 2,
    "name": "MyExtension",
    "description": "Some desc...",
    "version": "0.2",
    "background": {
        "scripts": ["js/jquery-2.1.4.min.js", "js/background.js", "...",
        "persistent": true
    },
    "default_locale": "en",
    "content_scripts": [
        {
            "matches": ["<all_urls>"],
            "js": ["js/jquery-2.1.4.min.js"]
        },
        {
          "matches": ["https://domain.tld/*"],
          "js": ["js/jquery-2.1.4.min.js", "js/contentscript.js"],
          "css" : ["css/contentscript.css",
          "run_at": "document_start"
        }
    ],

    "icons": {
        "16": "images/icon-16x16.png",
        "48": "images/icon-48x48.png",
        "128": "images/icon-128x128.png"
    },
    "browser_action": {
        "default_icon": "images/icon-128x128.png"
    },
    "permissions": [
        "cookies", "tabs", "alarms", "webRequest", "webRequestBlocking", 
        "contextMenus", "<all_urls>", "storage"
    ],

    "content_security_policy": "script-src 'self' 'unsafe-eval'; 
    object-src 'self'"
}

It is difficult for me to debug this behaviour, since I can´t exactly know when the Error Attempting to use a disconnected port object appears. It looks like the port doesn´t gets closed correctly after the sendResponse is executed and only if the index.html was opened.

Finally the shortened Error-Message:

Error: Attempting to use a disconnected port object
    at Error (native)
    at PortImpl.postMessage (extensions::messaging:65:22)
    at Port.publicClass.(anonymous function) [as postMessage] (extensions::utils:94:26)
    at responseCallback (extensions::messaging:163:16)

The idb-Functions are customized and won´t work like I wrote them here, but I just want to show what I´m doing there. I´m using .then() to sendReponse when the result is available and return true; to wait for the result if async. I also searched every script for onMessage and sendMessage. The listed functions related to onMessage/sendMessage are all that I´m using, they are not used elsewhere. I´m using a timer for indexhtml() to save an array containing the notifications in a specified interval and then executing a function at index.html to reload the notifications.

The index.html Tab gets opened via browserAction:

chrome.browserAction.onClicked.addListener(function(tab){
    chrome.tabs.create({url: chrome.extension.getURL('index.html')});
});
1 Answers
Related