Aspnetcore: Globale Ausnahmebehandlung

Erstellt am 26. Aug. 2019  ·  51Kommentare  ·  Quelle: dotnet/aspnetcore

Hallo Leute, ich wollte wissen, was der bessere Weg ist, um eine Ausnahme auf Anwendungsebene abzufangen, um zu vermeiden, try catch in alle meine Methoden und Komponenten einzufügen und die Ausnahmeverwaltung an einem Punkt zu zentralisieren (normalerweise eine Fehlermeldung anzeigen und die Ausnahme protokollieren). .

Gibt es also eine bessere Möglichkeit, dies in Preview8 zu tun, oder etwas, das für das RTM geplant ist?

Danke !

Components Big Rock affected-most area-blazor enhancement severity-major

Hilfreichster Kommentar

Irgendwelche Updates zu diesem Thema?

Derzeit reagiert meine serverseitige Blazor-App einfach nicht mehr auf Benutzereingaben, nachdem eine Ausnahme ausgelöst wurde.

Es ist keine gute Praxis, alle Codezeilen mit try-catch abzudecken (und auch nicht zu erwarten, dass der Entwickler dies tut). Im Falle einer "unvorhergesehenen" Ausnahme sollten wir einen generischen Handler haben, der uns Folgendes ermöglicht:

1.Wählen Sie, ob der Stromkreis unterbrochen werden soll.
2.Zeigen Sie unserem Benutzer eine "freundliche" GUI-Nachricht oder leiten Sie ihn einfach auf eine generische Fehlerseite weiter.

Derzeit kann die App nach einer nicht behandelten Ausnahme den Benutzer nicht über ein Problem benachrichtigen, und der Benutzer kann die App nur erneut ausführen (den Browser schließen und erneut zur App-URL wechseln) oder die Seite aktualisieren und den gesamten Status verlieren (was ist manchmal gut, aber der App-Entwickler sollte dies wählen).

Alle 51 Kommentare

Alle nicht behandelten Ausnahmen sollten im Logger landen. Wenn Sie etwas anderes sehen, lassen Sie es uns bitte wissen, und wir werden das gerne untersuchen. Ein Blick in die Protokolle sollte hier der richtige Weg sein.

OK, was ich verstehe, ist, dass ich meine eigene Implementierung von ILogger bereitstellen muss? und es liegt an meiner Implementierung, dass ich mich mit der Ausnahme befassen muss? (z. B. Benachrichtigung anzeigen, Ausnahme in eine Datei für die Serverseite schreiben und an die Steuerung für die Clientseite senden)
Eigentlich ist das einzige, was gefunden wird, dieses Paket https://github.com/BlazorExtensions/Logging
Ich verstehe nicht wirklich, wie man es benutzt, anscheinend können wir uns nur damit in die Konsole einloggen.

Aber selbst mit dieser Erweiterung stürzt die App ab, wenn der Code eine unbehandelte Ausnahme enthält.

Also, wenn ich das verstehe, habe ich nicht die Wahl, meinen gesamten Code mit try catch zu umgeben?

Danke für Ihre Erklärung

Jeder der hier aufgeführten Logger-Anbieter: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.2#built -in-logging-providers sowie von der Community entwickelte Anbieter ( https://github.com/aspnet/Extensions/tree/master/src/Logging#providers) sollte funktionieren.

Aber selbst mit dieser Erweiterung stürzt die App ab, wenn der Code eine unbehandelte Ausnahme enthält.

Bei serverseitigem Blazor sollte eine nicht behandelte Ausnahme die Verbindung trennen, aber die Anwendung nicht zum Absturz bringen. Wenn ein Block eine Ausnahme auslösen soll, die Sie tolerieren können, scheint ein try-catch der vernünftigste Weg zu sein, um fortzufahren. Was planen Sie mit nicht behandelten Ausnahmen zu tun, wenn Sie eine beliebige Ausnahme abfangen?

Clientseitiger Blazor protokolliert keine Ausnahmen. Sie werden nur auf die Konsole gedruckt. Hier ist der Code von WebAssemblyRenderer

protected override void HandleException(Exception exception)
{
    Console.Error.WriteLine($"Unhandled exception rendering component:");
    if (exception is AggregateException aggregateException)
    {
        foreach (var innerException in aggregateException.Flatten().InnerExceptions)
        {
            Console.Error.WriteLine(innerException);
        }
    }
    else
    {
        Console.Error.WriteLine(exception);
    }
}

Der einzige Weg, den ich gefunden habe, der Ausnahmen abfangen kann, wird hier beschrieben
https://remibou.github.io/Exception-handling-in-Blazor/

Aber ich würde das nicht Ausnahmebehandlung nennen ...

Ich hätte gerne einen globalen Ausnahmehandler, damit ich meinen Code ohne Catch-Blöcke schreiben könnte ...

{
   IsLoading = true;
   await SomeAsync();
}
finally
{
   IsLoading = false;
   //force rerender after exception
    StateHasChanged();
}

Wenn die SomeAsync-Methode eine Ausnahme auslöst, wird meine IsLoading-Variable auf „false“ gesetzt, aber meine Ansicht wird nicht erneut gerendert. Sie müssen SetStateHasChanged im finally-Block aufrufen, um das erneute Rendern der Ansicht zu erzwingen

Für den Client-seitigen Blazor schreibe ich endlich meine eigene Implementierung auf ILogger (inspiriert vom Code der Standardimplementierung, die sich in der Konsole anmeldet).
Mit dieser Implementierung kann ich einen LoggerController auf meinem Server aufrufen, in den auch ein ILogger injiziert wird (aber dieses Mal ist es eine NLog-Implementierung, die injiziert werden soll, damit ich alle Ausnahmen ordnungsgemäß auf dem Server schreiben kann).

Ich verlasse die Idee der globalen Ausnahmebehandlung, die nicht die Logik von Blazor zu sein scheint, und setze Try/Catch überall ein und injiziere einen ILoggerin allen Komponenten.

Außer wenn Sie der Meinung sind, dass es Besseres zu tun gibt, können Sie dieses Problem schließen.

Ich denke, das ist eine fehlende Funktion. Wenn eine Ausnahme ausgelöst wird, möchte ich auch einen zentralen Ort haben, an dem alle nicht behandelten Ausnahmen erfasst und etwas getan werden können. Entweder in einem Popup anzeigen, irgendwo protokollieren, an den Server senden oder was auch immer .. ohne Schaden für den App-Status
So etwas wie UnhandledException-Ereignis in WPF
https://docs.microsoft.com/en-us/dotnet/api/system.appdomain.unhandledexception?redirectedfrom=MSDN&view=netframework-4.8

Ist ILogger nicht schon so ein zentraler Ort?

@SteveSandersonMS , schau dir meinen Kommentar oben an
https://github.com/aspnet/AspNetCore/issues/13452#issuecomment -535227410
Ausnahmen (im clientseitigen Blazor) werden mit Console.Error.WriteLine in die Konsole geschrieben, sie werden nicht mit ILogger protokolliert. Sie könnten einen benutzerdefinierten TextWriter implementieren und Console.Error ersetzen
https://remibou.github.io/Exception-handling-in-Blazor/
aber Sie erhalten eine Zeichenfolgendarstellung einer Ausnahme.. Das Analysieren dieser Zeichenfolge, die einen Stack-Trace enthält, und der Versuch, (zum Beispiel) nur eine Ausnahmemeldung zu erhalten, ist zumindest umständlich.
Ich möchte einen Zugriff auf das Ausnahmeobjekt erhalten, damit ich meine eigene Protokollierung durchführen kann (oder was auch immer).

@rborosak Danke für die Klarstellung!

Irgendwelche Updates zu diesem Thema?

Derzeit reagiert meine serverseitige Blazor-App einfach nicht mehr auf Benutzereingaben, nachdem eine Ausnahme ausgelöst wurde.

Es ist keine gute Praxis, alle Codezeilen mit try-catch abzudecken (und auch nicht zu erwarten, dass der Entwickler dies tut). Im Falle einer "unvorhergesehenen" Ausnahme sollten wir einen generischen Handler haben, der uns Folgendes ermöglicht:

1.Wählen Sie, ob der Stromkreis unterbrochen werden soll.
2.Zeigen Sie unserem Benutzer eine "freundliche" GUI-Nachricht oder leiten Sie ihn einfach auf eine generische Fehlerseite weiter.

Derzeit kann die App nach einer nicht behandelten Ausnahme den Benutzer nicht über ein Problem benachrichtigen, und der Benutzer kann die App nur erneut ausführen (den Browser schließen und erneut zur App-URL wechseln) oder die Seite aktualisieren und den gesamten Status verlieren (was ist manchmal gut, aber der App-Entwickler sollte dies wählen).

@hagaygo Sehr gute Zusammenfassung!

@SteveSandersonMS Bitte berücksichtigen Sie dies für den 3.1.x-Meilenstein! Bitte verschieben Sie dies nicht auf 5.0.0

Hallo,

Ich erhalte diese Art von Fehler, wenn der Stromkreis in der Konsole des Entwicklerfensters unterbrochen wird.

image

Ich glaube derzeit sowieso nicht, dass der Benutzer benachrichtigt werden kann, dass danach ein Fehler auf dem Bildschirm aufgetreten ist, und ihn auffordern kann, ihn zu aktualisieren, ohne das Entwicklerfenster manuell zu öffnen, um die Seite zu überprüfen und zu aktualisieren

@SteveSandersonMS Könnten Sie klären, ob app.UseExceptionHandler() für serverseitigen Blazor funktioniert oder nicht?

Ich habe mehrere Fälle gesehen, in denen mein benutzerdefiniertes ErrorHandler keine Ausnahmen abfängt, die von meiner Anwendung ausgelöst werden. Beispielcode

Startup.cs :

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IServiceProvider serviceProvider)
{
    ...
    app.UseExceptionHandler(new ExceptionHandlerOptions { ExceptionHandler = ErrorHandler.HandleError });
    ...
}

ErrorHandler.cs :

public static async Task HandleError(HttpContext context)
{
    var error = context.Features.Get<IExceptionHandlerFeature>()?.Error;
    var message = error?.Message ?? "[EXCEPTION NOT FOUND]";        
    return;
}

Ein Beispiel ist, wenn mein Repository eine Ausnahme als solche auslöst:
The instance of entity type cannot be tracked because another instance with the same key value for {'Id'} is already being tracked

Meine MVC-Lösung fängt alle Ausnahmen ab und verwendet ähnliche ErrorHandling-Implementierungen.

Verschieben Sie dies in die 5.0 -Version, um die spezifischen Fragen hier zu destillieren und zu sehen, ob wir einige davon ansprechen können.

Das größte Problem für mich sind Fehlergrenzen . Ich möchte in der Lage sein, eine Komponente eines Drittanbieters zu verwenden und meine Verwendung dieser Komponente irgendwie in die Fehlerbehandlung einzuschließen, damit ein Fehler in der Bibliothek nicht meine gesamte Webanwendung zerstört. Im Moment gibt es keinen „Ort, an dem der Try-Catch platziert werden kann“ – der gesamte Komponentenbaum wird vom Blazor-Renderer überwacht, der stirbt, wenn irgendetwas tief im Baum durcheinander kommt.

+1 für diese Funktion.
Try/Catch-Block in alle Methoden einfügen zu müssen, ist kein vernünftiger Weg.

Ich persönlich habe früher eine Ausnahme ausgelöst, um Geschäftsfehler zu verwalten. Auf hoher Ebene fange ich die Ausnahme ab und entscheide je nach Typ, ob die Ausnahme protokolliert, dem Benutzer angezeigt werden muss und ob ich die vollständige Meldung (Business-Ausnahmen) oder nur ein "Etwas läuft schief" anzeigt. .

Eigentlich ist die einzige Möglichkeit, so etwas zu tun, eine ComponentBaseEx-Klasse zu erstellen, die von ComponentBase erbt und OnInitialized (Async), OnParametersSet (Async), ... überschreibt.
Leider muss ich auch bei diesem Weg alle Benutzeraktionen manuell verwalten (einen Kunden löschen, ...)

Denkst du
1) kann man was machen?
2) Wenn ja, wann?

Hier ist mein Szenario: Blazor-Desktop-/Hybrid-App mit Blazor-Server. Es meldet sich immer nur ein Benutzer an, und der Status bleibt auch nach dem Neuladen erhalten. Wenn es also eine nicht behandelte Ausnahme gibt, gibt es keine andere Möglichkeit, die App wieder in einen vertrauenswürdigen Zustand zu versetzen, als sie neu zu starten. Wir müssen unbehandelte Ausnahmen abfangen, entsprechende UX anzeigen und dann herunterfahren. Standard-Desktop-App-Muster.

Temporärer Hack: Wir haben die Protokollierung mit Serilog eingerichtet. Serilog verfügt über eine API, mit der Sie alle Protokollmeldungen filtern und entscheiden können, ob sie ausgegeben werden. Wir missbrauchen diese API, indem wir prüfen, ob ein Protokollereignis einen CircuitId -Schlüssel in seinem Eigenschaften-Wörterbuch hat. Wenn dies der Fall ist, bedeutet dies, dass eine Schaltung gestorben ist - dh es gibt eine nicht behandelte Ausnahme. Wir können die problematische Ausnahme aus dem von uns untersuchten Protokollnachrichtenobjekt erhalten. Presto - Sie haben die unbehandelte Ausnahme ganz oben in Ihren Händen und können damit machen, was Sie wollen.

Hallo Leute, wie die anderen bin ich wirklich besorgt, wenn Sie dies auf den .NET 5-Meilenstein verschieben.
Nach einem Jahr Arbeit an Blazor durch Umschreiben einer alten Silverlight-App werde ich voraussichtlich meine App im Mai/Juni in der Produktion bereitstellen (wenn Webassembly produktionsbereit sein wird).

Aber ich kann das definitiv nicht ohne eine starke Möglichkeit, alle unerwarteten Fehler abzufangen oder zumindest zu protokollieren.

Bitte denken Sie daran, vor der Veröffentlichung von 5.0 etwas zu machen, auch wenn es nicht perfekt ist (nur eine Methode mit der Ausnahme ist für mich in Ordnung, zumindest können wir loggen ...)

Vielen Dank!

Hallo, ich bin in der gleichen Situation wie @julienGrd
Bitte tun Sie etwas, um uns zu helfen/zu führen.
Grüße!

Bei mir geht es genauso.

Wir haben Blazor Server-Seite für unsere gesamte Entwicklung verwendet und von migriert
die Legacy-ASP.Net-Webseiten.

Am Dienstag, 3. März 2020 um 12:02 Uhr eliudgerardo [email protected]
schrieb:

Hallo, ich bin in der gleichen Situation wie @julienGrd
https://github.com/julienGrd
Bitte tun Sie etwas, um uns zu helfen/zu führen.
Grüße!


Sie erhalten dies, weil Sie kommentiert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/dotnet/aspnetcore/issues/13452?email_source=notifications&email_token=ANKYSDFSUQ3OTBGWQMRV5EDRFUZ27A5CNFSM4IPQWA62YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOENUJXLA#issuecomment-5965,5965 ,
oder abbestellen
https://github.com/notifications/unsubscribe-auth/ANKYSDGFCDRMZV2N4NLMOMLRFUZ27ANCNFSM4IPQWA6Q
.

--
Ankit Bansal

*Wissenschaftliche Spiele*

Die Absicht ist, dass Sie in der Lage sein sollten, alle nicht abgefangenen Ausnahmen mit der ILogger -Schnittstelle zu protokollieren. Das bedeutet, dass Sie Ihr eigenes benutzerdefiniertes Protokollierungssystem anschließen können, das mit den Ausnahmeinformationen macht, was Sie wollen.

Es gibt jedoch noch einen Teil davon, den wir noch nicht implementiert haben. Dies wird von https://github.com/dotnet/aspnetcore/issues/19533 verfolgt. Wir werden das sicher bald erledigen.

Sie sollten in der Lage sein, alle nicht abgefangenen Ausnahmen mit der ILogger-Schnittstelle zu protokollieren

@SteveSandersonMS Ich denke, was wir hier suchen, ist eine viel allgemeinere API, die Ihnen nur eine nicht abgefangene Ausnahme gibt, um zu tun, was wir wollen, _mit der Ausnahme selbst._ Stellen Sie sich vor, wir wollen die Ausnahme untersuchen und möglicherweise irgendwie reagieren, vielleicht senden Ausnahme zu einem Ausnahmeverfolgungsdienst wie Raygun, oder präsentieren Sie eine Benutzeroberfläche basierend auf den Inhalten. Ohne eine solche API müssen wir die ILogger -Schnittstelle missbrauchen, um all diese Dinge zu erreichen, was umständlich ist. Warum nicht einfach eine so viel allgemeinere API bereitstellen, anstatt alle möglichen Szenarien durch eine ILogger-Implementierung zu erzwingen?

Die Absicht ist, dass Sie in der Lage sein sollten, alle nicht abgefangenen Ausnahmen mit der ILogger -Schnittstelle zu protokollieren. Das bedeutet, dass Sie Ihr eigenes benutzerdefiniertes Protokollierungssystem anschließen können, das mit den Ausnahmeinformationen macht, was Sie wollen.

@SteveSandersonMS Haben Sie zufällig ein Referenzbeispiel, um dies in einer serverseitigen Blazor-App zu tun? Meine Absicht ist es, nach dem Protokollieren einer nicht abgefangenen Ausnahme dem Benutzer eine freundliche Nachricht anzuzeigen. Hilfe wird geschätzt. Grüße.

@eliudgerardo Blazor Server zeigt bereits einige Benutzeroberflächen an, wenn ein nicht behandelter Fehler auftritt. Sie können diese Benutzeroberfläche anpassen. Dokumente dazu finden Sie unter https://docs.microsoft.com/en-us/aspnet/core/blazor/handle-errors?view=aspnetcore-3.1#detailed -errors-during-development

@SteveSandersonMS Mir ist die von Ihnen erwähnte Option bekannt, aber ich fürchte, dass in diesem Fall der Verbindungsschaltkreis unterbrochen ist, und ich möchte nicht alle meine API-Aufrufe mit Try/Catch umschließen. Gibt es also eine Möglichkeit, dies zu erreichen?

@eliudgerardo Warum spielt es eine Rolle, dass der Stromkreis unterbrochen ist? Ist es Ihr Ziel, den Benutzer die Schaltung auch nach der nicht behandelten Ausnahme irgendwie weiter verwenden zu lassen?

@SteveSandersonMS Wir wollen nicht, dass der Stromkreis unterbrochen wird!. Wenn eine Ausnahme auftritt (in unserer App oder irgendwo in der von uns verwendeten Bibliothek eines Drittanbieters), möchten wir einen Ort, an dem wir einen Dialog mit der Meldung „Etwas ist schief gelaufen {Ausnahme.Nachricht}“ anzeigen könnten und die App weiterhin funktionieren würde. Wir haben eine Teillösung dafür, packen Lebenszyklusmethoden und unsere Methoden in den Try-Catch-Block, aber das ist umständlich und es gibt ein Problem mit Bibliotheken von Drittanbietern ...

@partyelite Wenn eine Ausnahme nicht behandelt wird, befindet sich diese Schaltung jetzt in einem unbekannten Zustand. Wir können nicht mehr sagen, ob irgendwelche Ressourcen darin noch nutzbar sind, ob Ihre Sicherheitslogik vollständig ausgeführt wurde oder irgendetwas anderes. Wenn die Schaltung weiterhin verwendet wird, kann dies zu undefiniertem Verhalten führen, einschließlich potenzieller Sicherheitsprobleme, die problematisch sind, da dieser Code auf Ihrem Server ausgeführt wird.

Eine Möglichkeit, die wir für die Zukunft in Betracht ziehen, ist ein optionaler Mechanismus „pro Komponente unbehandelte Ausnahme“. Wenn dieser Mechanismus aktiviert wäre, würde das Framework seine eigene try/catch -Logik um alle Aufrufe in den Lebenszyklusmethoden, Event-Handlern und der Rendering-Logik der Komponente ausführen. Wenn das Framework auf dieser Ebene eine Ausnahme abfängt, würde es diese einzelne Komponente als tot betrachten (und sie vielleicht in der Benutzeroberfläche durch eine Art „Fehler“-Komponente ersetzen), aber die Ausführung des Rests der Schaltung nicht beeinflussen.

Glauben Sie, dass diese Art von Ansatz Ihren Anforderungen entspricht?

Ich mag die Idee, eine eingebaute Komponentengrenze für Fehler zu haben.

Das wäre ausgezeichnet. Aber ich denke, wir brauchen immer noch eine Methode (die eine Ausnahme hat, die als Eingabeparameter aufgetreten ist), die wir überschreiben und etwas mit dieser Ausnahme machen könnten - z. B. einen Dialog mit Ausnahmedetails anzeigen oder Ausnahmedetails an den Server senden, auf dem sie protokolliert werden DB oder so..
Ich weiß, dass etwas Ähnliches jetzt mit ILogger durchgeführt werden kann, aber wir erhalten eine Zeichenfolge als Eingabeparameter, und das Abrufen einiger spezifischer Daten aus der Ausnahme in einem Zeichenfolgenformat ist wirklich schwierig.

Unbehandelte Ausnahmefallen pro Komponente wären sehr gut. Idealerweise wäre dies etwas, das extern und/oder in bestimmten Komponenten angegeben werden kann, sodass wir Teile der Benutzeroberfläche oder Funktionalität in Fehlergrenzen unterteilen können. Die Hauptnotwendigkeit besteht darin, etwas mit Semantik wie dieser tun zu können:

<MyApp>
    <HandleErrors>
        <ThirdPartyComponent />
    </HandleErrors>
    <HandleErrors>
        <SomeOtherComponent />
    </HandleErrors>
</MyApp>

Wenn eine der Komponenten nicht gerendert werden kann, müssen wir den Rest der Anwendung ausführen, um fortzufahren. Es entspricht einer Rich-Data-Desktopanwendung, in der Sie eine Seitenleiste präsentieren oder eine Geschäftslogikfunktion ausführen, die fehlschlägt, aber die App stürzt nicht ab und wirft keine Daten in Formularfeldern weg.

In etwas wie WPF mildert die Verwendung einer strikten Trennung von Ansichten und Modellen diese Bedenken. Best Practice ist die Verwendung von MVVM oder MVC oder was auch immer und eine Fehlerbehandlung um die Logik herum, die ausgelöst wird oder die die Ansicht aktualisiert. Blazor-idiomatische Ansichten sind jedoch zu zwingend und fehleranfällig, als dass dies vernünftig wäre. Es ist schwierig, eine .xaml-Datei zu schreiben, die die Anwendung zum Absturz bringt, aber in .razor ist es trivial, während des Renderns eine nicht behandelte Ausnahme zu haben, sei es von einer Datenbindung an eine ORM-unterstützte Eigenschaft oder einfach, weil Sie geschrieben haben

<strong i="7">@if</strong> (mightBeNull.Value) {
    <br>
}

Ist ILogger nicht schon so ein zentraler Ort?

Wie bei @julienGrd brauche ich eine Möglichkeit, MsalUiRequiredException global abzufangen, damit ich den Benutzer zu einer Anmeldung umleiten kann, um zusätzliche Bereiche anzufordern. In MVC gibt es einen Aktionsausnahmefilter, der dies behandelt, aber Blazor hat kein Äquivalent.

Vielleicht ist ILogger der Ort, an dem ich das irgendwie machen soll? Wenn ja, fühlt es sich schlecht an. Meine Ausnahme bezieht sich auf die Authentifizierung, also ist es ein Querschnittsthema, und ich brauche einen Weg, damit umzugehen, der nicht meine gesamte Anwendung verschmutzt.

@kenchilada Ich weiß, dass es sich anfühlt, als wäre das Hinzufügen eines "globalen" Ausnahmehandlers eine schnelle Lösung für Ihr Problem, aber jedes Mal, wenn Sie diesen Ansatz verwenden, verliert Ihr Code den Überblick über den laufenden Fluss. Sie haben keine Möglichkeit, den Zustand zu erhalten, und keine Möglichkeit, eine UX bereitzustellen, die nicht einfach alles wegwirft, was zu der Zeit vor sich ging. Im Allgemeinen ist es viel besser, einen bestimmten Try/Catch in die Benutzeroberfläche einzufügen, der ihn auslösen könnte, damit Sie fortfahren können, ohne den gesamten lokalen Status zu verwerfen.

Wenn Sie dies jedoch wirklich auf "globaler" Ebene handhaben möchten, dann ja, das ILogger ist eine Möglichkeit, dies zu tun.

Das Problem besteht darin, dass das Try-Catch-basierte Handling mit dem RenderTreeBuilder-Modell nicht möglich ist. Du kannst schreiben

<strong i="6">@try</strong>
{
    <p>@{throw new Exception();}</p>
}
catch (Exception e)
{
    <p>An error occurred.</p>
}

..aber es wird nicht "Ein Fehler ist aufgetreten." angezeigt, es wird die gesamte Schaltung herunterfahren. Sie erhalten nicht einmal das Konsolenprotokoll und #blazor-error-ui.

@SteveSandersonMS Ich stimme Ihnen in "Theorie" vollkommen zu, aber ich befinde mich in einem bestimmten Kontext, in dem ich nicht weiß, wie ich damit umgehen soll. Vielleicht haben Sie einige Antworten.

Ich synchronisiere viel Code von einer bestehenden Silverlight-App, die ich technisch zu Blazor migriere, behalte aber die Kompatibilität und teile den Code zwischen den beiden Apps, da der Arbeitsaufwand enorm ist und die beiden Apps eine Zeit lang nebeneinander funktionieren müssen .

Mein Problem ist also, dass das auf der Clientseite synchronisierte ViewModel wcf-Dienste wie folgt aufruft:
````
public void MyFunction(){
wcfClient.MyFunctionCompleted += MyFunctionCompleted;
wcfClient.MeineFunktion();
}

private void MyFunctionCompleted(object sender, MyFunctionCompletedArgs args){
//Ergebnis ist da, und auch eine mögliche Ausnahme
//Wir müssen diesen Code als nicht sicher betrachten, also haben Sie eine Möglichkeit, ihn abzufangen
}
````

Wenn ich also die Methode meines Ansichtsmodells in meiner Blazor-Ansicht aufrufe, ist es sinnlos, so etwas zu tun
private void ButtonClick(){ try{ myViewModel.MyFunction(); } catch(Exception ex){ //i can't catch the exception in the service or happened in the callback } }

Ich weiß also nicht, wie ich mit der Ausnahmerückgabe durch den Dienst umgehen soll, oder die Ausnahme ist direkt im Rückruf aufgetreten, ich habe die Hand verloren.

Danke für Ihre Hilfe !

In diesem Fall könnten Sie tatsächlich eine TaskCompletionSource verwenden. Nehmen wir an, dass MyFunctionCompletedArgs entweder eine Ausnahme oder einen Wert vom Typ TResult enthält, wäre es ungefähr so:

public Task MyFunction() 
{
    var tcs = new TaskCompletionSource<TResult>();
    wcfClient.MyFunctionCompleted += MyFunctionCompleted(tcs);
    wcfClient.MyFunction();
    return tcs.Task;
}

private EventHandler<TResult> MyFunctionCompleted(TaskCompletionSource<TResult> tcs) => (object sender, MyFunctionCompletedArgs args) =>
{
    if (args.Error != null)
    {
        tcs.SetException(args.Error);
    }
    else
    {
        tcs.SetResult(args.ReturnValue);
    }
};

Warten Sie dann auf der Blazor-Seite, bis das Versprechen abgeschlossen ist:

private async Task ButtonClick()
{
    try
    {
        await myViewModel.MyFunction();
    }
    catch (Exception ex)
    {
    }
}

Es gibt viele Programmier-/Softwareszenarien.

Meine Schlussfolgerung aus dieser Diskussion ist, dass Microsoft (zumindest derzeit) nicht möchte, dass wir Blazor für „große“ Apps oder LOB-Apps verwenden, da sie erwarten, dass wir überall Try/Catch-Blöcke platzieren.

Auf diese Weise können Sie vielleicht "kleine" Apps erstellen. (Außerdem, wie ich bereits erwähnte, ist es keine gute Praxis)

Aber LOB-Apps mit vielen Anwendungsfällen und 10-20 (und noch mehr) Entwicklern in einem Team können so nicht funktionieren.

Natürlich gibt es im Moment noch mehr Probleme mit Blazor, aber dieses Problem trat etwa 10-15 Minuten nach Beginn des Aufbaus eines POC auf.

Hallo,

Zu Recht gesagt. Hoffentlich wird Microsoft später in diesem Jahr ein Update bereitstellen.

Im Idealfall ist es nicht möglich, überall eine Fehlerbehandlung zu haben, und wenn der Stromkreis unterbrochen wird, weiß der Entwickler nicht, wohin er gehen soll. Wir sind Early Adopters von Blazor und waren Teil der Migration für eines meiner Unternehmensprojekte.

Es gibt eine Menge Dinge, die in Blazor poliert werden müssen.

Danke & Grüße,

Ankit Bansal

Wissenschaftliche Spiele

Von: Hagay Goshen [email protected]
Gesendet: Dienstag, 26. Mai 2020 00:21 Uhr
An: dotnet/aspnetcore [email protected]
Cc: bansalankit2601 [email protected] ; Kommentieren Sie [email protected]
Betreff: Re: [dotnet/aspnetcore] [Blazor] Globale Ausnahmebehandlung (#13452)

Es gibt viele Programmier-/Softwareszenarien.

Meine Schlussfolgerung aus dieser Diskussion ist, dass Microsoft (zumindest derzeit) nicht möchte, dass wir Blazor für „große“ Apps oder LOB-Apps verwenden, da sie erwarten, dass wir überall Try/Catch-Blöcke platzieren.

Auf diese Weise können Sie vielleicht "kleine" Apps erstellen. (Außerdem, wie ich bereits erwähnte, ist es keine gute Praxis)

Aber LOB-Apps mit vielen Anwendungsfällen und 10-20 (und noch mehr) Entwicklern in einem Team können so nicht funktionieren.

Natürlich gibt es im Moment noch mehr Probleme mit Blazor, aber dieses Problem trat etwa 10-15 Minuten nach Beginn des Aufbaus eines POC auf.


Sie erhalten dies, weil Sie kommentiert haben.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub an https://github.com/dotnet/aspnetcore/issues/13452#issuecomment-633799650 , oder kündigen Sie https://github.com/notifications/unsubscribe-auth/ANKYSDATEUMBPN43PYQU2ZDRTM7T3ANCNFSM4IPQWA6Q . https://github.com/notifications/beacon/ANKYSDD3JBBDUMUWMZ5NQXDRTM7T3A5CNFSM4IPQWA62YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEXDQHYQ.gif

Es gibt viele Programmier-/Softwareszenarien.

Meine Schlussfolgerung aus dieser Diskussion ist, dass Microsoft (zumindest derzeit) nicht möchte, dass wir Blazor für „große“ Apps oder LOB-Apps verwenden, da sie erwarten, dass wir überall Try/Catch-Blöcke platzieren.

Auf diese Weise können Sie vielleicht "kleine" Apps erstellen. (Außerdem, wie ich bereits erwähnte, ist es keine gute Praxis)

Aber LOB-Apps mit vielen Anwendungsfällen und 10-20 (und noch mehr) Entwicklern in einem Team können so nicht funktionieren.

Natürlich gibt es im Moment noch mehr Probleme mit Blazor, aber dieses Problem trat etwa 10-15 Minuten nach Beginn des Aufbaus eines POC auf.

Hier sind wir auch gelandet. Wir verwenden es für eine Backend-Verwaltungsschnittstelle, aber es ist im Moment viel zu neu, um es für unsere kundenorientierte Anwendung zu verwenden.

@gulbanana Danke für den Tipp! Ich bin mir nicht sicher, ob ich mit dieser Art von Code die Kompatibilität mit der Silverlight-App aufrechterhalten werde, aber ich muss es versuchen (auch wenn ich eine globale Ausnahmebehandlungslösung bevorzuge).

In diesem Fall könnten Sie tatsächlich eine TaskCompletionSource verwenden. Nehmen wir an, dass MyFunctionCompletedArgs entweder eine Ausnahme oder einen Wert vom Typ TResult enthält, wäre es ungefähr so:

public Task MyFunction() 
{
    var tcs = new TaskCompletionSource<TResult>();
    wcfClient.MyFunctionCompleted += MyFunctionCompleted(tcs);
    wcfClient.MyFunction();
    return tcs.Task;
}

private EventHandler<TResult> MyFunctionCompleted(TaskCompletionSource<TResult> tcs) => (object sender, MyFunctionCompletedArgs args) =>
{
    if (args.Error != null)
    {
        tcs.SetException(args.Error);
    }
    else
    {
        tcs.SetResult(args.ReturnValue);
    }
};

Warten Sie dann auf der Blazor-Seite, bis das Versprechen abgeschlossen ist:

private async Task ButtonClick()
{
    try
    {
        await myViewModel.MyFunction();
    }
    catch (Exception ex)
    {
    }
}

Ein bisschen verwirrt hier ... Wenn die globale Ausnahmebehandlung nicht machbar ist, warum gibt es dann ein Produkt da draußen?
für Blazor, der behauptet, dass "Alle nicht erfassten Ausnahmen automatisch protokolliert werden"?:
https://docs.elmah.io/logging-to-elmah-io-from-blazor/

@rono1 Sie können sich jetzt in die Protokollierungspipeline einklinken und Ausnahmen protokollieren - das bedeutet jedoch nicht, dass Sie die Ausnahme "behandelt" haben, sondern nur, dass Sie sie global protokollieren können. Ich bin aber dankbar für die Protokollierung!

Wir haben dieses Problem in den Backlog-Meilenstein verschoben. Dies bedeutet, dass für die kommende Version nicht daran gearbeitet wird. Wir werden den Rückstand nach der aktuellen Veröffentlichung neu bewerten und diesen Punkt zu diesem Zeitpunkt berücksichtigen. Um mehr über unseren Issue-Management-Prozess zu erfahren und bessere Erwartungen in Bezug auf verschiedene Arten von Issues zu haben, können Sie unseren Triage-Prozess lesen.

Eine Möglichkeit, die wir für die Zukunft in Betracht ziehen, ist ein optionaler Mechanismus „pro Komponente unbehandelte Ausnahme“. Wenn dieser Mechanismus aktiviert wäre, würde das Framework seine eigene try/catch -Logik um alle Aufrufe in den Lebenszyklusmethoden, Event-Handlern und der Rendering-Logik der Komponente ausführen. Wenn das Framework auf dieser Ebene eine Ausnahme abfängt, würde es diese einzelne Komponente als tot betrachten (und sie vielleicht in der Benutzeroberfläche durch eine Art „Fehler“-Komponente ersetzen), aber die Ausführung des Rests der Schaltung nicht beeinflussen.

Glauben Sie, dass diese Art von Ansatz Ihren Anforderungen entspricht?

@SteveSandersonMS Wird dies für die Implementierung in Betracht gezogen? Dies führt zu einer besseren Benutzererfahrung und robusterer Software.

+1 dazu. Wir sollen wirklich jedes einzelne Ereignis in ein try/catch ? Ich bin gerade in ein Kaninchenloch gegangen, um zu versuchen, dies mit einigen Basiskomponenten zu umgehen, um den Zustand zu verwalten, weil dies so schmerzhaft ist.

+1 auch dazu. Der Try/Catch-Ansatz ist wirklich keine Option für größere Lösungen mit mehreren Entwicklern.

Ich habe dies in meiner clientseitigen Blazor-App mithilfe eines benutzerdefinierten Protokollierungsanbieters behoben:
https://github.com/markusrt/NRZMyk/blob/master/NRZMyk.Client/ReloadOnCriticalErrorLogProvider.cs

Es scheint ein bisschen seltsam, einen Logger als globalen Ausnahmehandler zu verwenden, aber ich habe bis jetzt keinen saubereren Ansatz gefunden 😞

Das Blazor-Team muss definitiv etwas dagegen unternehmen
Anfrage/Ausgabe.

Am So, 4. Okt. 2020 um 15:24, Markus Reinhardt [email protected]
schrieb:

>
>
>

Ich habe dies in meiner clientseitigen Blazor-App mithilfe einer benutzerdefinierten Protokollierung behoben
Anbieter:

https://github.com/markusrt/NRZMyk/blob/master/NRZMyk.Client/ReloadOnCriticalErrorLogProvider.cs

Es scheint ein bisschen seltsam, einen Logger als globalen Ausnahmehandler zu verwenden, aber bei I
habe bisher keinen saubereren Ansatz gefunden 😞


Sie erhalten dies, weil Sie diesen Thread abonniert haben.
Antworten Sie direkt auf diese E-Mail und zeigen Sie sie auf GitHub an
https://github.com/dotnet/aspnetcore/issues/13452#issuecomment-703255415 ,
oder abbestellen
https://github.com/notifications/unsubscribe-auth/AEVARXEEHAOU532C26QCGXLSJBZRRANCNFSM4IPQWA6Q
.

Danke, dass sie uns kontaktiert haben.
Wir verschieben dieses Problem auf den Next sprint planning Meilenstein für zukünftige Auswertungen/Überlegungen. Wir werden die Anfrage auswerten, wenn wir die Arbeit für den nächsten Meilenstein planen. Um mehr darüber zu erfahren, was als nächstes zu erwarten ist und wie dieses Problem gehandhabt wird, können Sie hier mehr über unseren Triage-Prozess lesen.

Für alle, die nach einer clientseitigen Problemumgehung suchen:

function reportError(error) {
  if (DotNet) {
    DotNet.invokeMethodAsync('MyApp.Client', 'NotifyError', error);
  }
}

var exLog = console.error;
console.error = function (msg) {
  exLog.apply(console, arguments);
  reportError(msg);
}

window.addEventListener("unhandledrejection", function (promiseRejectionEvent) {
  reportError(promiseRejectionEvent.reason.message);
});
  public partial class AppLayout
  {
    [JSInvokable("NotifyError")]
    public static void NotifyError(string error)
    {
      //Handle errors
    }
  }

Browserunterstützung

Dies ist eine äußerst wichtige Funktion für eine Produktionsanwendung, und ich würde mich nicht wohl dabei fühlen, eine Anwendung zu veröffentlichen, bei der ich das Verhalten der Anwendung im Falle eines nicht behandelten Fehlers nicht kontrollieren oder zumindest zuverlässig protokollieren könnte. Glücklicherweise gibt es genug Unterstützung dafür in JavaScript, die wir nutzen können, aber es ist eine Lücke, die groß genug ist, um mich zu fragen, ob diese Technologie wirklich ausgereift genug ist, um in ernsthaften Anwendungen übernommen zu werden.

Ich hoffe, dass dieser globale Fehlerbehandler in zukünftigen Versionen priorisiert wird.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen