是否有可能捕获JavaScript异步回调中抛出的异常?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了是否有可能捕获JavaScript异步回调中抛出的异常?相关的知识,希望对你有一定的参考价值。

有没有办法捕获javascript回调中的异常?它甚至可能吗?

Uncaught Error: Invalid value for property <address>

这是jsfiddle:http://jsfiddle.net/kjy112/yQhhy/

try {
    // this will cause an exception in google.maps.Geocoder().geocode() 
    // since it expects a string.
    var zipcode = 30045; 
    var map = new google.maps.Map(document.getElementById('map_canvas'), {
        zoom: 5,
        center: new google.maps.LatLng(35.137879, -82.836914),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    });
    // exception in callback:
    var geo = new google.maps.Geocoder().geocode({ 'address': zipcode }, 
       function(geoResult, geoStatus) {
          if (geoStatus != google.maps.GeocoderStatus.OK) console.log(geoStatus);
       }
    );
} catch (e) {
    if(e instanceof TypeError)
       alert('TypeError');
    else
       alert(e);
}​
答案

它在你的例子中没有捕获任何东西的原因是因为一旦调用geocode()回调,try/catch块就结束了。因此,geocode()回调在try块的范围之外执行,因此不能被它捕获。

据我所知,不可能捕获JavaScript回调中抛出的异常(至少,不是以任何直接的方式)。

另一答案

是的,您可以覆盖window.onerror的默认行为:

window.onerror = function(message, file, lineNumber) {
  // all errors will be caught here
  // you can use `message` to make sure it's the error you're looking for
  // returning true overrides the default window behaviour
  return true; 
};
另一答案

您确实可以捕获JavaScript回调函数中触发的异常。

关键是在回调代码中设置try/catch块,因为在回调代码执行之前,回调代码之外的任何try/catch块都已经退出。因此,虽然上面的try/catch块无法捕获调用回调函数时抛出的任何异常,但您仍然可以执行以下操作:

// this will cause an exception ing google.maps.Geocoder().geocode() 
// since it expects a string.
var zipcode = 30045; 
var map = new google.maps.Map(document.getElementById('map_canvas'), {
    zoom: 5,
    center: new google.maps.LatLng(35.137879, -82.836914),
    mapTypeId: google.maps.MapTypeId.ROADMAP
});
// exception in callback:
var geo = new google.maps.Geocoder().geocode({ 'address': zipcode }, 
   function(geoResult, geoStatus) {
      try {
          if (geoStatus != google.maps.GeocoderStatus.OK) console.log(geoStatus);
      } catch(e){
          alert("Callback Exception caught!");
      }
   }
);

并且你将能够在抛出异常时捕获它。我不是100%确定是否会出现这种情况,所以我写了一些测试代码来验证。在Chrome 19.0.1055.1 dev上按预期捕获异常。

另一答案

我通过猴子修补控制台日志检测到错误。

if(window.console && console.error){
    var old = console.error;
    console.error = function(){
        if(arguments[0].indexOf('Google Maps API error')!=-1){
            alert('Bad Google API Key '+ arguments[0]);
        }
        Array.prototype.unshift.call(arguments);

        old.apply(this, arguments);
    }
}
另一答案

这是我的方法:

// the purpose of this wrapper is to ensure that any
// uncaught exceptions after a setTimeout still get caught
function callbackWrapper(func) {
    return function() {
        try {
            func();
        } catch (err) {
            // callback will reach here :)
            // do appropriate error handling
            console.log("error");
        }
    }
}

try {
    setTimeout(callbackWrapper(function() {throw "ERROR";}), 1000);
} catch (err) {
    // callback will never reach here :(
}

以上是关于是否有可能捕获JavaScript异步回调中抛出的异常?的主要内容,如果未能解决你的问题,请参考以下文章

捕获回调函数引发的错误

捕获在不同线程中抛出的异常

如何捕获ctypes中抛出的异常?

捕获 AuthenticationProvider 中抛出的异常

JavaScript 异常处理

如何捕获 node_modules 中抛出的异常