javascript:如何使用抑制回调中异常的LIB?
许多javascript库和框架接受在某些操作完成后调用的函数。例如:javascript:如何使用抑制回调中异常的LIB?,javascript,Javascript,许多javascript库和框架接受在某些操作完成后调用的函数。例如: chrome.storage.local.get( 'foo', function() { console.log( "foo" ); } ); 但我刚刚意识到一些API,包括上面提到的GoogleLocalStorage API,捕获并抑制被调用函数中的所有异常。例如,如果我修改了上面的代码,使其出现错误(ReferenceError,我希望在控制台中看到该错误): 不会引发任何错误,因为api通过捕获并忽略所有错误来抑
chrome.storage.local.get( 'foo', function() { console.log( "foo" ); } );
但我刚刚意识到一些API,包括上面提到的GoogleLocalStorage API,捕获并抑制被调用函数中的所有异常。例如,如果我修改了上面的代码,使其出现错误(ReferenceError
,我希望在控制台中看到该错误):
不会引发任何错误,因为api通过捕获并忽略所有错误来抑制它。在这种情况下如何调试我的代码?是否有任何方法可以恢复错误,或者所有这些api都不打算用于复杂的代码,我需要通过console.log
手动调试以查找失败的代码
更新1
只需将我自己的try-catch添加到所有回调中,就会给不太受欢迎的代码增加复杂性。此外,简单的console.log
比异常更糟糕,因为异常被开发工具捕获,显示为红色,附加了堆栈跟踪等。当然,所有这些都可以用console.log
模拟,但这将增加更大的复杂性
更新2
js代码忽略错误似乎是一种常见的做法,因此我被迫通过添加下划线插件来实现丑陋的解决方案,并使用它来封装每个回调:
function _safeblock( block )
{
console.assert( block );
return function() {
try {
block.apply( this, arguments );
}
catch( e ) {
console.log( e.message, e.stack );
}
};
}
function _safecall( block )
{
console.assert( block );
_safeblock( block )();
}
_.mixin({
safeblock: _safeblock,
safecall: _safecall,
});
你可以自己抓
chrome.storage.local.get( 'foo', function() {
try{
a.b();
}catch(e){
console.log(e);
//do whatever
}
});
您可以通过重写storage.local.get
或创建通用函数包装器来自动执行此操作
您还可以使用setTimeout手动延迟函数,这将使库无法(在浏览器中)抑制您的错误
chrome.storage.local.get( 'foo', function() {
setTimeout(function(){
a.b();
});
});
但是,这不会给您提供非常有意义的堆栈跟踪(函数之外的任何内容都不会显示),这使得它不太有用。如果在性能敏感的情况下使用此选项,也可能会造成性能开销(在浏览器中,setTimeout至少需要几毫秒的时间,但它周围有一个postMessage hack)。您只需执行一个try-catch并使用
控制台。错误
(适用于Firebug和Chrome开发工具,不确定其他工具):
如果回调不需要参数,可以创建一个包装函数:
function wrapTryCatch(func)
{ return function ()
{ try { func.apply(this, arguments); }
catch (e)
{ var err = e.name + ': ' + e.message;
console.error ? console.error(err)
: console.log ? console.log(err)
: alert(err);
}
}
}
保护所有API调用中的所有回调会增加代码的复杂性。你是对的,而且会。您必须代理所有API方法或尝试/捕获所有API调用。为API编写一个包装器。在API IMO中,抑制所有异常是一个糟糕的设计调用,特别是如果您没有提供类似“调试模式”的东西。对于JS以外的语言也是如此。在所有API调用中保护所有回调将增加代码复杂性。@EyeofHell:这不可能不是一个必要的问题,但我会做更多的研究。我不是说这是一个问题,除非我找到更好的方法,否则我将使用这种方法。但我不喜欢在没有任何明确理由的情况下给代码增加复杂性。也许这个问题是众所周知的,它类似于google chrome或全局java设置中的隐藏开关,将事情变回正常状态。@EyeofHell问题是已知的,解决方法是不编写这样做的API。在node中,您可以使用域来解决这个问题。@BenjaminGruenbaum很奇怪
google
使用这种糟糕的做法:(.你最终做了什么来解决这个问题?@BenjaminGruenbaum我通过将每个第三方回调封装到安全代码中实现了一个丑陋的解决方案。但这只是一个暂时的破解,不是一个合适的架构解决方案。
chrome.storage.local.get('foo', function ()
{ try { a.b(); }
catch (e) { console.error(e.name + ": " + e.message); }
});
function wrapTryCatch(func)
{ return function ()
{ try { func.apply(this, arguments); }
catch (e)
{ var err = e.name + ': ' + e.message;
console.error ? console.error(err)
: console.log ? console.log(err)
: alert(err);
}
}
}