webentwicklung-frage-antwort-db.com.de

Ist es möglich, Ausnahmen abzufangen, die in einem asynchronen Callback von JavaScript ausgelöst werden?

Gibt es eine Möglichkeit, Ausnahmen in JavaScript-Callbacks abzufangen? Ist es überhaupt möglich?

Uncaught Error: Invalid value for property <address>

Hier ist das 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);
}​
56
anewb

Der Grund, warum es in Ihrem Beispiel nichts fängt, ist, dass nach Aufruf des geocode()-Callbacks der try/catch-Block beendet ist. Daher wird der geocode()-Callback außerhalb des Gültigkeitsbereichs des try-Blocks ausgeführt und kann von diesem nicht erfasst werden. 

Soweit ich weiß, ist es nicht möglich, Ausnahmen zu erwischen, die in JavaScript-Callbacks (zumindest nicht auf einfache Art und Weise) geworfen werden.

64
Daniel Vassallo

Ja, Sie können das Standardverhalten von window.onerror überschreiben:

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; 
};
39
Jivings

Sie können tatsächlich Ausnahmen feststellen, die innerhalb einer JavaScript-Rückruffunktion ausgelöst werden.

Der Schlüssel besteht darin, den try/catch-Block im Callback-Code einzurichten, da try/catch-Blöcke außerhalb des Callback-Codes bis zur Ausführung des Callback-Codes bereits beendet sind. Während Ihr try/catch-Block oben keine Ausnahmen fangen kann, die ausgelöst werden, wenn die Rückruffunktion aufgerufen wird, können Sie dennoch Folgendes tun:

// 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!");
      }
   }
);

und Sie können die Ausnahme erfassen, wenn sie ausgelöst wird. Ich war mir nicht 100% ig sicher, ob das der Fall sein würde oder nicht, also schrieb ich Testcode, um das zu überprüfen. Die Ausnahme wird wie erwartet in Chrome 19.0.1055.1 dev erfasst.

15
Justin Houk

Ich habe den Fehler entdeckt, indem Affen die Konsolenprotokolle patchen.

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);
    }
}
1
Karan Bhandari

Hier ist mein Ansatz:

// 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 :(
}
0
Martin Konecny