使用 Chrome API 时未选中 runtime.lastError

Posted

技术标签:

【中文标题】使用 Chrome API 时未选中 runtime.lastError【英文标题】:Unchecked runtime.lastError when using Chrome API 【发布时间】:2015-04-10 11:24:43 【问题描述】:

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

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

如何解决这个错误?

【问题讨论】:

可能你应该使用 TRY ... CATCH 块。 @Seti 在这种情况下无济于事。 那么也许你可以给我们你在 chrome.filesystem 周围使用的代码? @Seti 查看我关于为什么try ... catch 无法捕捉到它的答案。 @Xan 谢谢!你的回复很有帮助~ 【参考方案1】:

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

这是什么错误?

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 统一使用 this 而不是错误参数。 事实上,引用 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 在出现错误时看到您检查该值(即在您的回调中对其进行评估),就不会抛出错误。

【讨论】:

是这样想的,但是如果他添加了他正在使用的代码,并且我们看到他的回调无法清除错误 - 我们可以更快地回答它。 感谢您的回复,非常有帮助! @zcfrank1st 没问题。还澄清了这不是检查错误的唯一方法,而是跨 Chrome API 的统一方法。 难以置信的答案!感谢您花时间写这篇文章。 我从未说过我认为这是一个好的架构,但事实就是如此——Chrome API 早期的设计决策。我不是 Chrome 开发团队的一员,所以我无法告诉你为什么选择它。【参考方案2】:

聚会迟到了,但这是我在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 中测试

【讨论】:

未捕获的类型错误:无法读取未定义的属性“删除” @Jordan chrome.windows 是扩展 API 的一部分。如果您尝试从常规网页中使用它,chrome.windows 不存在,给您看到的错误。【参考方案3】:

对于此类错误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);

【讨论】:

【参考方案4】:

此错误与Already addressed here 中的某些 google chrome 扩展有关。我禁用了所有扩展,错误消失了。在与它们中的每一个玩了一段时间之后,我发现导致它的原因是 Natural Reader Text to Speech 扩展。很有可能您有一个扩展程序导致了这种情况。祝你好运。

【讨论】:

以上是关于使用 Chrome API 时未选中 runtime.lastError的主要内容,如果未能解决你的问题,请参考以下文章

获得对 background.js 的响应时:未选中 runtime.lastError:无法建立连接

使用useState(Reactjs)时未选中材料表复选框

使用 Chrome + XHR 时未定义 PHP POST 变量

Chrome 在关闭/退出时未清除 SESSION COOKIES

复选框设置日期,但在表单加载时未选中:需要加载事件吗?

重力形式:AJAX 加载的复选框在错误验证时未选中