javascript:如何使用libs来抑制回调中的异常?

时间:2013-10-17 12:10:58

标签: javascript

许多javascript库和框架接受在某些操作完成后调用的函数。例如:

chrome.storage.local.get( 'foo', function() { console.log( "foo" ); } );

但我刚刚意识到一些API,包括上面提到的google local storage api,会捕获并抑制被调用函数中的所有异常。例如,如果我修改上面的代码以出现错误(我想在控制台中看到ReferenceError):

chrome.storage.local.get( 'foo', function() { a.b(); } );

由于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,
});

2 个答案:

答案 0 :(得分:3)

你可以尝试自己抓住它们。

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黑客攻击它)。

答案 1 :(得分:2)

你可以简单地执行try-catch并使用console.error(适用于Firebug和Chrome DevTools,不确定其他人):

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);
        }
    }
}