4

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

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

但我刚刚意识到一些 API,包括上面提到的谷歌本地存储 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,
});
4

2 回答 2

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 hack)。

于 2013-10-17T12:16:56.480 回答
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);
        }
    }
}
于 2013-10-17T12:17:13.770 回答