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

ane*_*ewb 60 javascript google-maps exception callback

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

Uncaught Error: Invalid value for property <address>
Run Code Online (Sandbox Code Playgroud)

这是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);
}?
Run Code Online (Sandbox Code Playgroud)

Dan*_*llo 69

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

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

  • @anewb,给丹尼尔斯回答√ (10认同)
  • 问题是"它甚至可能吗?" 这是一个很好的答案,@ BlakeRegalia. (2认同)
  • 逻辑,正是我开始关注这个问题时所担心的.我遇到了一个案例,我不控制的代码抛出了我需要捕获的异常,但我不能因为它是异步的...... (2认同)

Jiv*_*ngs 38

是的,您可以覆盖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; 
};
Run Code Online (Sandbox Code Playgroud)


小智 15

您确实可以捕获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!");
      }
   }
);
Run Code Online (Sandbox Code Playgroud)

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

  • 如果异常没有在回调代码中抛出,而是由异步函数抛出,会发生什么.异步函数在其处理中的某个时刻抛出错误,这意味着我们的try catch都不会捕获它.我目前正面临这个问题.让我知道你认为可以做些什么. (2认同)
  • **这个答案是错误的**。抛出是由异步线程中的“abcf()”函数完成的。换句话说,您的回调甚至不会被调用,因为回调之前出现错误。只有当回调函数通过调用已实现的函数来配合时,实现者决定将该错误转移到您的回调函数,这个答案才是正确的,这会将错误抛出到您的回调函数。 (2认同)
  • @Pacerier 接受的答案在说“不可能捕获 JavaScript 回调中抛出的异常”时也是错误的。因此,这是一个有用的附加项。 (2认同)