Wenn Sie sich den qUnit-Quellcode ansehen, gibt es zwei Mechanismen, die Ausnahmen behandeln. Einer wird von config.notrycatch
Einstellung gesteuert und wird Test Setup, Ausführung und Teardown in try..catch
Blöcke umbrechen. Diese Herangehensweise wird mit Ausnahmen, die von asynchronen Tests ausgelöst werden, nicht viel helfen, aber qUnit ist dort nicht der Aufrufer. Aus diesem Grund gibt es einen zusätzlichen window.onerror
Handler, der von der Test.ignoreGlobalErrors
Einstellung gesteuert wird. Beide Einstellungen sind standardmäßig false
, so dass beide Arten von Ausnahmen abgefangen werden. In der Tat, der folgende Code (wie bei Ihnen im Wesentlichen gleich, aber ohne TinyMCE spezifische Teile) erzeugt die erwarteten Ergebnisse für mich:
test("foo", function()
{
stop();
function myfun(ed)
{
start();
ok(1, 'entered qunit again');
throw "bar";
}
setTimeout(myfun, 1000);
});
ich zum ersten Mal eines bestandenen Tests mit der Meldung „eingegeben QUnit wieder“ und dann einem failed eins mit der Nachricht: "uncaught exception: bar." Wie, warum Sie dies nicht funktioniert, kann ich folgende Optionen:
- Ihre QUnit Kopie mehr als zwei Jahre alt ist, bevor qUnit issue 134 wurde behoben und ein globaler Exception-Handler hinzugefügt.
- Ihr Code ändert sich
Test.ignoreGlobalErrors
Einstellung (unwahrscheinlich).
- Es gibt einen vorhandenen
window.onerror
-Handler, der true
zurückgibt und somit qUnit mitteilt, dass der Fehler behoben wurde. Ich habe überprüft, ob TinyMCE standardmäßig einen hinzufügt, aber es sieht nicht so aus.
- TinyMCE fängt Fehler in Ereignishandlern auf, wenn sie aufgerufen werden. Dies ist die logische Sache zu tun, wenn Sie mit mehreren Rückrufe zu tun, ist der übliche Ansatz etwas wie folgt aus:
for (var i = 0; i < callbacks.length; i++)
{
try
{
callbacks[i]();
}
catch (e)
{
console.error(e);
}
}
Durch alle Ausnahmen zu console.error
Umleitung dies stellt sicher, dass Ausnahmen sind nach wie vor berichtet, während alle Callbacks selbst dann aufgerufen werden, wenn einer von ihnen eine Ausnahme auslöst. Da die Ausnahme jedoch behandelt wird, kann jQuery sie nicht mehr abfangen. Auch hier habe ich überprüft, ob TinyMCE dieses Muster implementiert - es sieht nicht so aus.
Update: Es gibt eine fünfte Option, an die ich nicht gedacht habe: Die Ausnahme wird innerhalb eines Rahmens ausgelöst und qUnit hat seinen globalen Fehlerhandler dort nicht eingerichtet (bereits, weil Tracking-Frame-Erstellung nicht ist -trivial, ein neuer Rahmen kann jederzeit erstellt werden).Dies sollte durch Hinzufügen des folgenden Code an dem Rahmen leicht behoben werden:
window.onerror = function()
{
if (parent.onerror)
{
// Forward the call to the parent frame
return parent.onerror.apply(parent, arguments);
}
else
return false;
}
Bezüglich Ihrer Neben Anmerkung: die console
Objekt nicht garantieren Ihnen eine bestimmte Reihenfolge, in der Nachrichten angezeigt werden. Tatsächlich zeigt der Code console.log("foo");throw "bar";
auch zuerst die Ausnahme, gefolgt von der Protokollnachricht. Dies weist darauf hin, dass Protokollmeldungen in die Warteschlange gestellt und möglicherweise aus Leistungsgründen verzögert verarbeitet werden. Aber Sie müssen in Firefox die Implementierung des console
Objekts überprüfen, um sicher zu sein - das ist ein Implementierungsdetail.
Danke für eine ausführliche Antwort. Während "window.onerror" eine Funktion ist, sind 'window.frames [0] .onerror' und' window.frames [0] .frames [0] .onerror' null, wo Tests stattfinden. Es scheint, dass qUnit wurde nicht entworfen, um mit iframes zu laufen? Ich nehme an, ich könnte die Frames als Onerror der Frames festlegen oder sie irgendwie nennen, ich bin mir nicht sicher, ob es einen weniger hacky Weg gibt? Denkst du, qUnit wäre der empfohlene Ansatz dafür, nicht etwas wie Selenium oder andere? – NoBugs
@NoBugs: Siehe mein Update. Was die Verwendung von qUnit betrifft - warum nicht? Es ist natürlich eine Frage der Vorlieben, aber Selen ist im Allgemeinen komplizierter anzuwenden. –