han*_*rik 2 javascript error-handling promise
与人们想象的不同,以下代码不会触发 window.error 处理程序
window.addEventListener("error",function(error){
alert("uncaught error somewhere!");
});
(async function(){
let foo= ((await ( await fetch("/no_json_plz_i_want_an_error")).json()));
})();
Run Code Online (Sandbox Code Playgroud)
(根据对此问题的评论,原因是“因为错误发生在承诺上下文中”:why does not fetch().json()Errors trigger window.onerror?)
将其显式传播到窗口错误处理程序的正确方法是什么?这也不起作用,由于某种原因它仍然不会传播到 window.error:
(async function(){
let foo= ((await ( await fetch("/no_json_plz_i_want_an_error")).json()));
})().catch(function(err){
throw err;
});
Run Code Online (Sandbox Code Playgroud)
这似乎也不起作用(为什么?不知道)
(async function(){
let foo= ((await ( await fetch("/no_json_plz_i_want_an_error")).json()));
})().catch(function(err){
let ev = new ErrorEvent(err.message, err);
window.dispatchEvent(ev);
});
Run Code Online (Sandbox Code Playgroud)
这种方法失败并出现错误Uncaught (in promise) DOMException: Failed to execute 'dispatchEvent' on 'EventTarget': The event provided is uninitialized.,无论这意味着什么
(async function(){
let foo= ((await ( await fetch("/no_json_plz_i_want_an_error")).json()));
})().catch(function(err){
let ev= document.createEvent("ErrorEvent");
ev.error=err;
window.dispatchEvent(ev);
});
Run Code Online (Sandbox Code Playgroud)
那么..正确的做法是什么?
您可以使用unhandledrejection事件来捕获窗口对象中的承诺错误。
编辑:
因为 fetch() 仍然会返回响应对象并且不会抛出错误。当为 false 时,您可以抛出错误response.ok。参见下面的函数run1:
该run2函数将抛出一个 JSON 令牌错误,因为它response.ok是 false,并且它会尝试解析数据。
您可以尝试在本地环境中运行,因为 fiddle 可能会将错误处理包装在控制台中。
window.addEventListener("unhandledrejection", function (e) {
console.log("Error occurred: " + e.reason.message);
});
(async function run1() {
try {
let response = await fetch("/no_json_plz_i_want_an_error");
if (response.ok) {
const data = response.json();
} else {
throw new Error("Unable to fetch()");
}
} catch (err) {
throw new Error(err);
}
})();
(async function run2() {
try {
await (await fetch("/no_json_plz_i_want_an_error")).json();
} catch (err) {
throw new Error(err);
}
})();Run Code Online (Sandbox Code Playgroud)