使用Chrome API时未选中runtime.lastError

问题描述 投票:0回答:6

我在应用程序中使用

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

运行时未选中

runtime.lastError
fileSystem.chooseEntry
:用户已取消

如何修复这个错误?

javascript google-chrome-extension google-chrome-app
6个回答
117
投票

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

这个错误是什么?

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 看到您在出现错误时

检查了
该值(即在回调中对其进行了评估),就不会抛出错误。

聚会迟到了,但以下是我在

chrome.windows.remove()

8
投票

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 中,您可以使用更短的

箭头函数

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

在 Chrome 64 中测试

    

对于这种类型的错误

try catch

5
投票
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);

此错误与
已在此处解决

0
投票

只是分享我的案例;


0
投票

res.end()

来自 Nodejs 应用程序上的 http 标头


使用 Manifest v3,大多数 chrome API 调用现在都会返回 Promise,但是对于少数情况,您在许多情况下必须实现检查 chrome.runtime.lastError 的回调。


0
投票

const promisifyLastErrorFunc = (fn) => { return (...args) => { return new Promise((resolve, reject) => { fn(...args, (result) => { if (isValid(chrome.runtime.lastError)) { reject(chrome.runtime.lastError); } else { resolve(result); } }); }); }; };

使用就很简单了:

  const createContextMenu = utils.promisifyLastErrorFunc(
    chrome.contextMenus.create);

  await createContextMenu({
    id: 'myContextMenu',
    title: 'My Menu',
    contexts: ['all'],
  });

这解决了未检查的 LastError 消息的问题,让我可以通过 async/await 处理所有事情。

	

© www.soinside.com 2019 - 2024. All rights reserved.