使用Chrome API时未经检查的runtime.lastError

时间:2015-02-10 12:18:42

标签: javascript google-chrome-extension google-chrome-app

我在我的应用中使用chrome.fileSystem API来打开文件。单击文件选择器对话框的Cancel按钮时,会出现错误:

  运行runtime.lastError时取消选中fileSystem.chooseEntry:用户已取消

如何解决此错误?

3 个答案:

答案 0 :(得分:51)

在这种情况下,这个错误并不重要,但我会解释它以及如何摆脱它。

这是什么错误?

Chrome API大多是异步的:您有一个在操作完成时调用的回调。

如果是chrome.fileSystem.chooseEntry,所选条目(或条目)将被传递给回调:

chrome.fileSystem.chooseEntry(
  {/* options */},
  function(entry) {
    // This is the callback for the API call; you can do something with entry
  }
);

但是,API不会保证产生结果。例如,在您的情况下,用户可以通过单击“取消”拒绝提供访问权限。然后没有可以使用的条目,您可能想要解释为什么会发生这种情况。如何在不使用额外的“错误”参数污染所有回调的情况下引发错误?

通常,Chrome会在调用回调时设置全局变量chrome.runtime.lastError来处理此问题。 在Chrome异步API中统一使用此而不是错误参数。实际上,引用chrome.fileSystem文档:

  

通过chrome.runtime.lastError通知所有失败。

  • 如果一切顺利,那就是undefined
  • 如果出现问题,它将非空,chrome.runtime.lastError.message会解释错误。

但是,某些回调没有检查此错误变量。这可能表示编程错误,Chrome添加了在回调中实际检查(评估)chrome.runtime.lastError的检查。如果没有,它认为这是一个未处理的异常,并抛出此错误。

为什么我说它不重要?

虽然这是一个错误,但它不会破坏程序的执行(它在异步任务结束时抛出),并且不会真正显示给您的用户。

虽然我说这不重要,但你应该检查程序的逻辑。它可能是也可能不是 - 这是一个(严厉的)警告。

为什么会存在?

警告,开发人员,您的代码可能会尝试使用不存在的结果,因为出现了问题。

您可能已经在检查错误,例如

if (entry) {
  // Process entry
} else {
  // Something went wrong (but what?)
}

Chrome不会使用复杂的启发式方法来查看您的代码是否期望这种可能性。如上所述,错误是通过chrome.runtime.lastError报告的,您需要检查错误。

请注意,只有在 发生错误时才会出现此错误,而不是在API调用正常结束时引发此错误。

我可以抓住它吗?

不是真的;它不是由您的代码引发的,而是由处理Chrome API中的异步任务的清理代码引发的;因此在回调中使用try ... catch无济于事。由于它是异步的,因此在原始API调用周围使用try也无济于事。

该怎么办?

您应该为回调添加逻辑,以便按照Chrome预期的方式检查问题,并可能对此做出反应。

function(entry) {
  if(chrome.runtime.lastError) {
    // Something went wrong
    console.warn("Whoops.. " + chrome.runtime.lastError.message);
    // Maybe explain that to the user too?
  } else {
    // No errors, you can use entry
  }
}

只要Chrome在发生错误时(即在回调中对其进行评估)看到您检查该值,就不会抛出错误。

答案 1 :(得分:4)

派对迟到了,但是我在chrome.windows.remove()电话中如何抑制错误,万一它可以帮助其他人。而不是

chrome.windows.remove(foo);  // unconditional; runtime.lastError not checked

我用过

chrome.windows.remove(
        foo,
        function ignore_error() { void chrome.runtime.lastError; }
);

void计算其操作数,然后返回undefined。我认为这段代码相当有效地证明了它的目的是忽略错误:)。

为简便起见,ignore_error()可以退出此调用并用于多个chrome API调用,或者可以省略名称ignore_error

更新在ES6中,您可以使用较短的arrow function语法:

chrome.windows.remove( foo, ()=>void chrome.runtime.lastError );

在Chrome 64中测试

答案 2 :(得分:0)

对于此类错误try catch不会有帮助。相反,您可以在上面的令人敬畏的响应中提到的@xan访问全局变量chrome.runtime.lastError(顺便说一句,你应该阅读它并提升它!)。

现在,我在这里提供一个可以使用的示例:

function catchLastError(){
  if(chrome.runtime.lastError){
    console.log("error: ", chrome.runtime.lastError);
  }else{
    // some code goes here.
  }
}

chrome.fileSystem.chooseEntry(yourEntry,catchLastError);