| 

.NET C# Java Javascript Exception

5
Etwas mehr Regelmäßigkeit täte diesem Blog gut. Daher fange ich mal wieder mit einem kleineren Eintrag an. Eigentlich alle Projekte implementiere ich im Flow Design, auch mein Team habe ich dazu angehalten. In einem kürzlichen Review ist mir etwas aufgefallen. Nehmen wir folgende Implementierung von zwei Komponenten die über eine Action miteinander verbunden sind. Zudem […]

Etwas mehr Regelmäßigkeit täte diesem Blog gut. Daher fange ich mal wieder mit einem kleineren Eintrag an. Eigentlich alle Projekte implementiere ich im Flow Design, auch mein Team habe ich dazu angehalten. In einem kürzlichen Review ist mir etwas aufgefallen.

Nehmen wir folgende Implementierung von zwei Komponenten die über eine Action miteinander verbunden sind. Zudem behandelt die erste Komponente eventuelle Fehler (alternativ auch die zweite, das ist hier aber nicht relevant).

image

Anhand der Grafik würden wir erwarten, dass Fehler in der ersten Komponente an der ErrorHandler weitergeleitet und dort verarbeitet werden. Weiterhin erwarten wir, dass nach erfolgreicher Verarbeitung die zweite Komponente aktiviert wird und ihre Verarbeitung beginnt. Wir interpretieren die Verbindung von “Component A” nach “Component B” als Nachricht oder Datenfluss.

Soweit ist alles in Ordnung. Doch es gäbe diesen Beitrag nicht, wenn keine Probleme auftreten könnten. Schauen wir und nachfolgendes beispielhaftes Protokoll an (in der Annahme es ist zusätzlich ein Logger integriert)

…, Component A, Process startet
…, Component A, Process completed
…, Component B, Process startet
…, ErrorHandler, Exception raised …
…, App, Terminated

“Component B” ist in diesem Beispiel nicht an dem “Error Handler” angeschlossen. Trotzdem wird dieser aktiviert und ändert den Programmfluss auf ungewollte Weise. Unabhängig ob Fehler bei der Implementierung dafür verantwortlich sind, unsere Annahme “Component A” ist mit der Verarbeitung nicht fertig, stimmt hier nicht. Die Komponente hat keine Nachricht an die Nachfolger gesendet, die Komponente hat einen Aufruf weiterer Komponenten über eine Aktion gestartet.

Was hier skizziert wurde ist nur ein Beispiel, in der Praxis lag das Problem zwischen unzähligen Komponenten und Verknüpfungen. Einigen wird bereits klar sein wie es dazu kam. Hier folgt die Erklärung.

// Component A

public void Process()
{
try
{
  // ..
  Completed(data);
}
catch (Exception ex)
{
  HandleError(ex);
}
}

public event Action<Exception> HandleError = delegate {};

public event Action<string> Completed = delegate {};

// Component B

public void Process()
{

var service = new Service();
try
{
  // …
}
catch (Exception)
{
  // …
}
finally
{
  service.Disconnect();
}

// Beispiel Verknüpfung

a.Completed += logger.WriteLine;
a.Completed += b.Process;
a.HandlerError += logger.Error;

 

Sieht erst mal nicht besonders böse aus, und würden möglicherweise viele so implementieren. Hier wurde erwartet, dass auch “Component B” ihre Fehler in irgendeiner Weise verarbeitet. Der Fehler trat jedoch im finally Block auf und “Component A” war mit ihrer Verarbeitung eben noch nicht fertig, sondern stand in der Funktion Process() beim Aufruf der Action Completed.

Fazit

Erwartungshaltungen aufgrund von Spezifikationen sollten im Idealfall mit Tests implementiert werden. Ich bezweifle aber, das derartige Fälle oft in Tests zu finden sind. Wir können bei dieser Art Flow Design mit Actions nicht erwarten, das die Verarbeitung von Komponenten abgeschlossen ist, wenn eine Action aufgerufen wird.


event-based-components flow review
Weitere News:
Schreibe einen Kommentar:
Themen:
review flow event-based-components
Entweder einloggen... ...oder ohne Wartezeit registrieren
Benutzername
Passwort
Passwort wiederholen
E-Mail