Laden...

Vorgehensweise Umgang mit Fehlern MVVM

Erstellt von CodeF vor 4 Jahren Letzter Beitrag vor 4 Jahren 1.876 Views
C
CodeF Themenstarter:in
12 Beiträge seit 2020
vor 4 Jahren
Vorgehensweise Umgang mit Fehlern MVVM

Hi, wie wäre für folgendes der richtige Weg?

In einer MVVM-Anwendung würde aus der Businesslogik heraus eine Methode in einer Klasse für einen Datenimport per CSV aufgerufen. Diese ist für das Laden und das Aufbereiten der Daten zuständig. Nun können da ja verschiedene Fehler passieren:

  • Datei nicht zugreifbar
  • Daten nicht auswertbar
  • Version der Datendatei veraltet

Bei manchen dieser Fehler würde eine Exception auslösen und wird daher mit einem Try/Catch abgefangen, andere würden per Code bei der Auswertung entstehen.

Wie wird nun die BL und der Anwender über diese Fehler informiert? In der CVS-Laden-Klasse sollen keine MsgBoxen und sowas enthalten sein.

Möglichkeiten wären meiner Meinung nach:

  • Rückgabewert über Enum
  • Exceptions und eingene Exceptions
  • ?

Wie sieht das aus wenn ein Backgroundworker verwendet wird was durchaus sinnvoll ist?

Gruß

16.806 Beiträge seit 2008
vor 4 Jahren

Prinzipiell Exceptions; das sieht das gesamte .NET Konzept so vor.
Gibt dazu in den .NET Guidelines auch eine eigene Sektion, wie, weshalb und warum.

2.298 Beiträge seit 2010
vor 4 Jahren

So strikt würde ich es jetzt nicht unbedingt machen. Bei API's und größeren Projekten handhaben wir es meist so, dass jede Methode der BusinessLogik einen entsprechenden Rückgabetyp hat.

Für das lesen von Daten aus der Datenbank beispielsweise etwas wie:


public class GetUserDataResult
{
      ///
      // Gets or sets if getting user data succeeded
      ///
      public bool Success { get; set; }
      
      ///
      // Gets or sets the error text if the data call failed
      ///
      public string Error { get; set; }

      ///
      // Gets or sets the user data
      ///
      public UserData UserData { get; set }
}

Success und Error kommen hier natürlich aus einer gemeinsamen Basisklasse für Aufrufergebnisse.

Klar würde es auch mit Exceptions bis Stelle x ausreichen. Wir reden aber im von CodeF genannten Fall von erwarteten Fehlern die auch entsprechend behandelt werden sollten.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

2.078 Beiträge seit 2012
vor 4 Jahren

Und warum könnte man diesen erwarteten Fehlern nicht einfach einen eigenen Exception-Typ (oder Ableitungen davon pro Fehler) geben?

So muss man diese Klasse überall hin durch reichen und wenn man das Mal nicht tut (vergessen, Faulheit, etc.), gehen diese Fehlerinformationen verloren.

Mit einer Exception ist das egal.
Man muss (soll) sie nirgendwo beachten, wo man sie nicht behandeln kann. Sobald man sie behandeln kann, kann man auch ein try-catch schreiben und diesen eigenen Exception-Typ abfangen.
Das musst Du am Ende sowieso, denn es kann ja immer noch eine Exception auftreten.

16.806 Beiträge seit 2008
vor 4 Jahren

Bei APIs macht man das aufgrund vom Technologiebruch, zB .NET auf JSON.
Bei APIs ohne Technologiebruch bzw. ohne Auswirkung des Bruchs wie zB WCF oder gRPC, macht man das i.d.R. nicht.

Wenn also kein Workaround notwendig ist, dann ist so ein vorgehen unnütz bzw. Kontraproduktiv.

Eine solche Klasse in der Business Logik stufe ich persönlich als großen Designfehler ein.
Er bricht klar die Empfehlungen und Prinzipien von Software Architektur in dem Bereich.

2.298 Beiträge seit 2010
vor 4 Jahren

Das ändert m.E. nichts am oben genannten Szenario wo wir von erwarteten Fehlern reden. Die sollten auf keinen Fall als Exception nach außen geworfen werden sondern eigentlich zuvor schon abgefangen / behandelt werden.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

2.078 Beiträge seit 2012
vor 4 Jahren

Eine Exception kann sowohl erwartet als auch unerwartet sein.

Die unerwarteten Exceptions sollten nicht gefangen oder zumindest weiter geworfen werden.

Die erwarteten Exceptions sollte man erst dann fangen, wenn man sie auch wirklich behandeln kann. Sie vorher abzufangen und mit weniger Infos in ein eigenes Objekt zu packen, macht meiner Meinung nach überhaupt keinen Sinn.

C
CodeF Themenstarter:in
12 Beiträge seit 2020
vor 4 Jahren

Ich hab mir die NET Guidelines und auch "Best Practices für Ausnahmen" angeguckt.

So wie ich es verstanden habe, ist da das Mittel der Wahl Exception. Aber nur wenn nicht schon davon augegangen wird, das ein Fehler auftritt. Darum gibt es dann die z.B. TryParse-Methoden. Die sollen dann vorrangig verwendet werden.
=> Fehlervermeidung zuerst, und dann erst Exceptions!

Nur wie sieht es aus, wenn Exceptions innerhalb eines Backgroundworkers erzeugt werden?

Mann kann in der WorkerComplete-Methode das e.Error abfragen und schauen, ob allgemeine oder eine eigene Exception ausgelöst wurde. Hier müsste dann aber die Exception neu geworfen werden um den Fehler an die aufrufende Klasse weiterzuleiten. Leider funktioniert dies bei mir nicht. Führt dann zu einen Fehler in der mscor.lib.

Wie denkt Ihr darüber?

16.806 Beiträge seit 2008
vor 4 Jahren

Ich denke so darüber, dass man den Backgroundworker prinzipiell gar nicht mehr braucht, da es mittlerweile eben Tasks gibt, die quasi jeden Verwendungszweck des Backgroundworkers übernommen haben.

Rein prinzipiell kann man aber auch mit dem Backgroundworker so programmieren, das das Handhaben von Exceptions kein Problem ist.
Das ist dann "einfach" das Thema von Software Architektur und der Anwendung von Code Pattern.

C
CodeF Themenstarter:in
12 Beiträge seit 2020
vor 4 Jahren

Guten Morgen,

irgendwie komme ich da nicht zurecht.

Wenn ich davon ausgehe dass eine länger andauernde Sache mittels Backgroundworker ausgeführt wird um die GUI nicht zu blockieren ist der Ablauf doch so:

  1. Aus den GUI-Thread wird eine Methode aufgerufen z.B. LoadData

  2. In dieser Methode LoadData wird ein Backgroundworker zur Arbeit herangezogen und gestartet

  3. Das Programm kehrt in den GUI-Thread zurück da ja jetzt der BW die Arbeit macht

  4. Im Backgroundworker wird eine Exception ausgelöst

  5. In der Mehtode ...WorkerCompleted ist die Exception mittels Abfrage von e.Error abfragbar

Wie und auf welche weise soll nun der GUI-Thread über diese Exception benachrichtigt werden?
Auch wenn in der ...WorkerCompleted -Methode eine neue Exception geworfen wird, wer soll diese Abfangen? Der Aufruf aus 1. ist ja schon lange vorbei.

2.298 Beiträge seit 2010
vor 4 Jahren

Im einfachsten Falle gibt es dafür Events.

Der BackgroundWorker allerdings ist ein schlechtes Beispiel. - Denn im WorkerCompleted musst du keine weitere Exception werfen. Du kannst den Fehler direkt auswerten und in irgend einer Art und Weise ausgeben.

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

C
CodeF Themenstarter:in
12 Beiträge seit 2020
vor 4 Jahren

Hi, evt. hab ich das dann falsch aufgebaut oder verstanden.

Der Backgroundworker befindet sich nun mal in meiner Klasse für das Laden.

In dieser möchte ich aber nichts mit Fehlerausgabe oder sowas machen (MVVM).

Wie isz hier nun die richtige vorgenhensweise. Events? Und dann? Doch wieder über Argumente die Fehler melden?