在单页面Web应用程序中,有时需要将新的javascript块附加到页面上。
假设我们有以下脚本标记内容,它们有语法错误,例如缺少引号。它必须是一个错误,它在分析时引发异常而不是运行时。
var test = {"foo":1, "bar":"test, "baz":"foobar"};
现在,您创建一个新的脚本元素,将文本注入内部并将其附加到DOM:
var text = 'var test = {"foo":1, "bar":"test, "baz":"foobar"};';
var node = document.createElement('script');
node.appendChild(document.createTextNode(text));
head.appendChild(node);
当然,在最后一行,抛出了“SyntaxError”异常。
问题是将最后一行放在try catch块中不起作用,异常永远不会被捕获。我设法使用旧的脏window.onerror事件捕获错误,但只在Chrome上。例如,在IE11上,如果禁用了脚本错误,则只能在控制台打开的情况下使用。
所以问题是,如何可靠地捕获此异常以便能够向用户显示消息?
由于
答案 0 :(得分:0)
不确定是否有办法捕获它,但如果您可以控制加载的脚本,您当然可以使用以下解决方法知道何时发生错误。
问题是SyntaxError没有通过" onerror",而是用" onload"完成。 所以hack是在源脚本的末尾插入一个小的标志/赋值语句,并在" onload"回调,除了使用" onerror"。
捕获其他错误答案 1 :(得分:0)
为了捕获SyntaxError,可以使用window.addEventListener('error', ...)
方法并阻止默认设置。一些示例代码:
var sourceCode = ...;
await new Promise((resolve, reject)=>{
var script = document.createElement('script');
script.type = 'module';
script.innerHTML = sourceCode + '\n' +
'if(window.scriptLoadedHook){window.scriptLoadedHook();}';
var windowErrorHandler = (event) =>{
event.preventDefault();
var error = event.error;
error.stack = error.stack + '\n\n' + sourceCode;
window.removeEventListener('error', windowErrorHandler);
reject(error);
};
window.addEventListener('error', windowErrorHandler);
var rejectHandler = (error) =>{
window.removeEventListener('error', windowErrorHandler);
reject(error);
};
script.addEventListener('error', rejectHandler);
//script.onerror = rejectHandler;
script.addEventListener('abort', rejectHandler);
//script.onabort = rejectHandler;
var loadedHandler = ()=>{
window.removeEventListener('error', windowErrorHandler);
resolve();
};
script.addEventListener('load', loadedHandler);
script.onload = loadedHandler;
var body = document.getElementsByTagName('body')[0];
try {
body.appendChild(script);
} catch(error){
reject(error);
}
})
.catch(error => {
console.warn('Could not process JavaScript code:\n', error);
})
.then(()=>{
//refresh app etc.;
});
});