有没有办法捕获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);
}
答案 0 :(得分:68)
它在您的示例中不会捕获任何内容的原因是因为一旦调用geocode()
回调,try/catch
块就结束了。因此,geocode()
回调在try
块的范围之外执行,因此不能被它捕获。
据我所知,不可能捕获JavaScript回调中抛出的异常(至少,不是以任何直接的方式)。
答案 1 :(得分:39)
是的,您可以覆盖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;
};
答案 2 :(得分: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!");
}
}
);
并且您将能够在抛出异常时捕获它。我不是100%确定是否会出现这种情况,所以我写了一些测试代码来验证。在Chrome 19.0.1055.1 dev。
上按预期捕获异常答案 3 :(得分:1)
我通过猴子修补控制台日志检测到错误。
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);
}
}
答案 4 :(得分:0)
这是我的方法:
this.build["results"] = { pass: 0, fail: 0};
答案 5 :(得分:0)
根据所有答案,try / catch +回调在不同的上下文中设置,但是,那么-您将如何解释这段代码try / catch的工作原理?
function doSomeAsynchronousOperation(cb) {
cb(3);
}
function myApiFunc() {
/*
* This pattern does NOT work!
*/
try {
doSomeAsynchronousOperation((err) => {
if (err) {
console.log('got here');
throw err;
}
});
} catch (ex) {
console.log(ex);
}
}
myApiFunc();
答案 6 :(得分:0)
如果您可以使用Promises和async / await,则可以如下面的示例代码所示解决该问题:
async function geocode(zipcode) {
return new Promise((resolve, reject) => {
const g = new google.maps.Geocoder().geocode({ 'address': zipcode }, function(geoResult, geoStatus) {
if (geoStatus != google.maps.GeocoderStatus.OK) {
reject(new Error("Callback Exception caught"));
} else {
resolve(g);
};
});
});
}
try {
// ...
// g will be an instance of new google.maps.Geocoder().geocode..
// you can resolve with desired variables
const g = await geocode(zipcode);
// ...
} catch( e ) {
console.log(e);
}