我在应用程序中使用
chrome.fileSystem
API 来打开文件。当我单击文件选择器对话框的 Cancel
按钮时,出现错误:
运行时未选中
runtime.lastError
:用户已取消fileSystem.chooseEntry
如何修复这个错误?
在这种情况下,这个错误并不重要,但我会解释它以及如何消除它。
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.runtime.lastError
。如果不是,它认为这是一个未处理的异常,并抛出此错误。
为什么我说不重要?虽然我说这并不重要,但您应该检查程序的逻辑。它可能会也可能不会 - 这是一个(严厉的)警告。
它为何存在?,您的代码可能尝试使用不存在的结果,因为出现了问题。 您可能已经在检查错误,例如
if (entry) {
// Process entry
} else {
// Something went wrong (but what?)
}
Chrome 不会采用复杂的启发式方法来查看您的代码是否期望这种可能性。如前所述,错误是通过
chrome.runtime.lastError
报告的,您需要检查它。
请注意,此错误仅在发生不良情况时才会引发,而不是在 API 调用正常完成时引发。我能抓住它吗?
try ... catch
没有帮助。由于它是异步的,因此在原始 API 调用周围使用 try
也无济于事。
该怎么办?
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()
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 );
对于这种类型的错误
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);
此错误与已在此处解决
res.end()
来自 Nodejs 应用程序上的 http 标头
使用 Manifest v3,大多数 chrome API 调用现在都会返回 Promise,但是对于少数情况,您在许多情况下必须实现检查 chrome.runtime.lastError 的回调。
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 处理所有事情。