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 :(
}