AngularJS mit globaler $ http-Fehlerbehandlung

9

Ich möchte bestimmte $http -Fehlerszenarien global abfangen und verhindern, dass Controller die Fehler selbst behandeln. Ich denke, dass ich einen HTTP-Interceptor brauche, aber ich bin mir nicht sicher, wie ich meine Controller davon abbringen kann, auch den Fehler zu behandeln.

Ich habe einen Controller wie folgt:

%Vor%

Und ein HTTP-Interceptor wie folgt:

%Vor%

Dies funktioniert, sofern der Browser zum Pfad '/ error' umleitet. Aber die Verheißung catch in HomeController wird auch ausgeführt, und ich will das nicht.

Ich weiß, ich könnte HomeController so codieren, dass es einen 404-Fehler ignoriert, aber das ist nicht pflegbar. Angenommen, ich modifiziere HttpInterceptor , um auch 500 Fehler zu behandeln, müsste ich dann HomeController erneut modifizieren (ebenso wie alle anderen Controller, die seither hinzugefügt wurden und $http verwenden). Gibt es eine elegantere Lösung?

    
Snixtor 25.05.2016, 06:16
quelle

5 Antworten

17

Option 1 - Abbruch / Abbruch der Versprechenskette

Eine kleine Änderung in HttpInterceptor kann dazu dienen, die Versprechenskette zu unterbrechen / abzubrechen, was bedeutet, dass weder activateOk noch activateError auf dem Controller ausgeführt werden.

%Vor%

Die Zeile return $q(function () { return null; }) löscht das Versprechen.

Ob das "ok" ist, ist ein Diskussionsthema. Kyle Simpson in " Sie nicht kenne JS nicht "sagt:

  

Viele Promise Abstraktionsbibliotheken bieten Möglichkeiten zum Abbrechen   Versprechen, aber das ist eine schreckliche Idee! Viele Entwickler wünschen Promises   war ursprünglich mit externen Stornierungsmöglichkeiten entwickelt worden, aber   das Problem ist, dass es einen Verbraucher / Beobachter eines Versprechens lassen würde   die Fähigkeit eines anderen Verbrauchers beeinflussen, dasselbe Versprechen zu halten.   Dies verletzt die Vertrauenswürdigkeit des Zukunftswertes (externe Unveränderbarkeit),   aber mehr ist die Verkörperung der "Fernwirkung"   Anti-Pattern ...

Gut? Schlecht? Wie gesagt, es ist ein Diskussionsthema. Ich mag die Tatsache, dass es keine Änderung an bestehenden $http -Kunden erfordert.

Kyle hat recht, wenn er sagt:

  

Viele Promise-Abstraktionsbibliotheken bieten Möglichkeiten, Promises abzubrechen ...

Die Bluebird Promise-Bibliothek bietet beispielsweise Unterstützung für die Stornierung. Von der Dokumentation :

  

Die neue Kündigung hat "egal" Semantik während der alten   Abbruch hatte Semantik abzubrechen. Ein Versprechen zu annullieren bedeutet einfach   dass seine Handler Callbacks nicht aufgerufen werden.

Option 2 - Eine andere Abstraktion

Versprechen sind eine relativ breite Abstraktion. Aus der Promises / A + Spezifikation :

  

Ein Versprechen repräsentiert das mögliche Ergebnis einer asynchronen Operation.

Der Dienst Angular $http verwendet die $q -Implementierung von Versprechen, eine Zusage für das eventuelle Ergebnis einer asynchronen HTTP-Anforderung zurückzugeben.

Es ist nichts wert, dass $http zwei veraltete Funktionen hat, .success und .error , die das zurückgegebene Versprechen schmücken. Diese Funktionen waren veraltet, weil sie nicht in der typischen Weise verkettet werden konnten, die Versprechungen sind, und es wurde angenommen, dass sie nicht viel Wert als eine "HTTP-spezifische" Menge von Funktionen hinzufügen.

Aber das soll nicht heißen, dass wir nicht unsere eigene HTTP-Abstraktion / Wrapper erstellen können, die nicht einmal die zugrundeliegende Verheißung, die von $http verwendet wird, preisgibt. So:

%Vor%

Da dies kein Versprechen ist, muss auch sein Konsum etwas anders funktionieren:

%Vor%

Im Fall von 404 wird die Position in 'error' geändert, und weder getSuccess noch getError Callbacks werden ausgeführt.

Diese Implementierung bedeutet, dass die Möglichkeit, HTTP-Anfragen zu ketten, nicht mehr verfügbar ist. Ist das ein akzeptabler Kompromiss? Die Ergebnisse können variieren ...

Option 3 - Dekorieren Sie die Ablehnung

Dankeschön an TJ für seinen Kommentar:

  

Wenn Sie eine Fehlerbehandlung in einem bestimmten Controller benötigen, benötigen Sie   Bedingungen, um zu prüfen, ob ein Fehler in   Abfangjäger / Service usw.

Der HTTP-Interzeptor kann die Ablehnung des Versprechens mit einer Eigenschaft handled dekorieren, um anzugeben, ob der Fehler behandelt wurde.

%Vor%

Controller sieht dann so aus:

%Vor%

Zusammenfassung

Im Gegensatz zu Option 2 bleibt bei Option 3 für alle $http -Kunden die Option, Versprechen zu verketten, was insofern positiv ist, als dass die Funktionalität nicht eliminiert wird.

Beide Optionen 2 und 3 haben weniger "Fernwirkung". Im Falle von Option 2 macht die alternative Abstraktion deutlich, dass sich die Dinge anders verhalten als die übliche $q Implementierung. Und für Option 3 wird der Verbraucher das Versprechen erhalten, mit ihm zu tun, wie es ihm gefällt.

Alle 3 Optionen erfüllen die Wartbarkeitskriterien, da Änderungen an der globalen Fehlerbehandlungsroutine, um mehr oder weniger Szenarien zu handhaben, keine Änderungen an den Konsumenten erfordern.

    
Snixtor 26.05.2016, 00:41
quelle
3

Wrap $http in Ihrem eigenen Service. Auf diese Weise müssen Sie, wenn Sie die Fehlerbehandlungslogik ändern müssen, nicht alle Ihre Controller ändern.

Etwas wie:

%Vor%     
T J 25.05.2016 06:29
quelle
2

In diesem Artikel wird erläutert, wie Sie http-Aufrufe abfangen und verschiedene Vorgänge ausführen können. Einer von ihnen behandelt Fehler.

Eine kurze Kopie einfügen aus dem obigen Artikel ...

%Vor%     
Stian Standahl 25.05.2016 06:44
quelle
1
%Vor%     
sudil ravindran pk 25.05.2016 06:39
quelle
0

Probieren Sie es aus

factory / golfalErrorHandler.js

%Vor%

app.js

%Vor%     
Ravi 25.05.2016 07:13
quelle

Tags und Links