Chrome扩展程序错误:“运行browserAction.setIcon时未选中runtime.lastError:没有带标识的选项卡”

时间:2014-09-09 00:29:49

标签: javascript google-chrome google-chrome-extension race-condition

我正在为我的Google Chrome扩展程序编码,我在后台脚本中设置了应用程序的图标:

try
{
    objIcon = {
        "19": "images/icon19.png",
        "38": "images/icon38.png"
    };

    chrome.browserAction.setIcon({
        path: objIcon,
        tabId: nTabID

    });
}
catch(e)
{
}

请注意,我将调用包装在try / catch块中。

但是,有时我在控制台日志中收到以下消息:

  

运行browserAction.setIcon时未经检查的runtime.lastError:否   标签:11618。

很难调试此错误,因为它似乎仅在我关闭或重新加载Chrome标签时出现,它没有行号或任何信息供我跟踪,加上它&# 39;不容易通过调试器运行(即我不能在发生错误时设置断点,但如果我在chrome.browserAction.setIcon()线上盲目设置断点,我就不会再看一下日志中的消息。)

所以我很好奇是否有人可以建议如何解决这个错误?

编辑:只是发布更新。我仍然无法解决此问题。 @abraham在下面提出的建议提供了一个有点工作的方法,但它是安全的。例如,在选项卡关闭的情况下,如果选项卡尚未关闭,我可以调用他建议的chrome.browserAction.setIcon(),但在其回调函数中,选项卡最终可能会关闭,因此任何连续调用需要相同标签ID的其他API,比如setBadgeBackgroundColor(),可能仍会给我相同的No tab with id例外。换句话说,对于那些了解本地编程的人来说,这是一个典型的竞争条件情况。而且我不确定它是否是Chrome中的错误,因为很明显JS不提供任何线程同步方法...

在进行测试时,我多次目睹了这种行为。它并不经常发生,因为我们正在谈论非常精确的时序情况,但它确实发生了。因此,如果有人找到解决方案,请在下面发布。

2 个答案:

答案 0 :(得分:23)

加入回调并检查chrome.runtime.lastError

objIcon = {
    "19": "images/icon19.png",
    "38": "images/icon38.png"
};

function callback() {
    if (chrome.runtime.lastError) {
        console.log(chrome.runtime.lastError.message);
    } else {
        // Tab exists
    }
}

chrome.browserAction.setIcon({
    path: objIcon,
    tabId: nTabID

}, callback);

答案 1 :(得分:0)

以下对我有用

/** 
 * Update icon, text and background
 * Handle the case where the tab_id no longer exists
 */
function updateIconAndBadge(tab_id, icon_path, badge_text, badge_background_color) {

    // Set the icon path
    chrome.browserAction.setIcon({ path: icon_path, tabId: tab_id },
        // Call back
        () => {
            // Check for error
            if (chrome.runtime.lastError) {
                // Failed - tab is gone
                console.log(`Tab ${tab_id} no longer exists.`);
            }
            else {

                // Ok - Set the badge text 
                chrome.browserAction.setBadgeText({
                    tabId: tab_id,
                    text: badge_text
                });

                // Set the back ground colour
                chrome.browserAction.setBadgeBackgroundColor({
                    tabId: tab_id,
                    color: badge_background_color
                });
            }
        });
}