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

zcf*_*1st 25 javascript google-chrome-extension google-chrome-app

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

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

如何解决这个错误?

Xan*_*Xan 59

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

这个错误是什么?

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
  }
);
Run Code Online (Sandbox Code Playgroud)

但是,不保证 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?)
}
Run Code Online (Sandbox Code Playgroud)

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

请注意,这个错误是当坏事只养发生时API调用正常完成,而不是.

我可以抓住它吗?

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

怎么办呢?

您应该为回调添加逻辑,以便按照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
  }
}
Run Code Online (Sandbox Code Playgroud)

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

  • 令人难以置信的答案!感谢您花时间写这篇文章。 (2认同)
  • 我从来没有说过我认为这是一个好的架构,但它就是这样 - 在 Chrome API 的早期某个地方的设计决定。我不是 Chrome 开发团队的成员,所以我无法告诉你为什么选择它。 (2认同)

cxw*_*cxw 5

晚到聚会了,但是这是我在chrome.windows.remove()呼叫中抑制错误的方法,以防万一对其他人有帮助。代替

chrome.windows.remove(foo);  // unconditional; runtime.lastError not checked
Run Code Online (Sandbox Code Playgroud)

我用了

chrome.windows.remove(
        foo,
        function ignore_error() { void chrome.runtime.lastError; }
);
Run Code Online (Sandbox Code Playgroud)

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

为简便起见,ignore_error()可以将其从此调用中拔出并用于多个chromeAPI调用,或者ignore_error可以省略名称。

更新在ES6中,可以使用较短的箭头函数语法:

chrome.windows.remove( foo, ()=>void chrome.runtime.lastError );
Run Code Online (Sandbox Code Playgroud)

在Chrome 64中测试


ism*_*iet 5

对于这种类型的错误try catch不会有帮助。相反,您可以访问全局变量,chrome.runtime.lastError如 @xan 在上面的精彩回复中提到的那样(顺便说一下,您应该阅读它并投票!)。

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

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

chrome.fileSystem.chooseEntry(yourEntry,catchLastError);
Run Code Online (Sandbox Code Playgroud)