angenommen, Ihr habt einen Web-Dienst, der Fehler-Codes zurück liefern können soll, wenn etwas schief gegangen ist.
Diese Fehler-Codes sollen konkrete Fehlerquellen identifizieren können, sodass man auf dieser Basis z.B. eine Support-Liste anbieten kann.
Oder wir haben eine Web-API und definieren Fehler-Codes, anhand derer ein Client spezifisch reagieren kann, ohne dass Exception-Details raus gegeben werden müssen.
Wie würdet Ihr das umsetzen?
Einfach in jedem Request eine Reihe von catches und so jeden bekannten Fehler abfangen und um einen Fehler-Code ergänzen?
Oder würdet Ihr eigene Exception-Typen definieren und je Situation die Exceptions fangen und als InnerException weiter geben?
Mich stört dabei, dass...
... man relativ weit oben viele mögliche Exceptions kennen und abfangen können muss, nach einer Änderung im Detail muss man also auch bei diesen catches prüfen und hat Probleme, wenn mehrere Exception-Typen in unterschiedlichen Situationen unterschiedliche Fehler-Codes bedeuten können.
... man für alles Mögliche eigene Exception-Typen definieren muss und ein neues Catch in einer Methode das Exception-Handling der aufrufenden Methode kaputt machen kann, weil die einen anderen Exception-Typ erwartet.
Meine Idee war daher die, dass ganz zum Schluss alle Exceptions generisch (Exception-Typ) gefangen und anschließend der StackTrace abgesucht wird.
Je StackFrame bzw. MethodBase kann man dann mittels Attributen ein Exception-ErrorCode-Mapping aufbauen, das nur für diese Methode gilt.
Das heißt:
Wenn ich eine Methode implementiere, bemerke ich direkt, dass es einige mögliche Fehlerquellen gibt, die ich nicht behandeln kann. Soll einer dieser Fehler als Fehler-Code behandelt werden, kann ich als Attribut definieren, welcher Exception-Typ zu welchem Fehler-Code führen soll, ggf. mit ein paar zusätzlichen Bedingungen, z.B. InnerExceptions.
Wenn die Exception gefangen wird, findet mein System diese MethodBase und das Attribute und kann - wenn die Bedingungen erfüllt sind - den Fehler-Code zurück geben.
Und dann könnte man noch Features einbauen, wie z.B. ...
- die Möglichkeit, Mappings einer aufgerufenen Methode zu überschreiben oder nicht
- Suchen von Mappings in der Klasse oder Basis-Methode/Klasse
- Verschiedene Matching-Strategien (selber Typ, zuweisbar, etc.)
Im Code könnte es so aussehen:
[ErrorCode("ZB001", typeof(FileNotFoundException))]
[ErrorCode("ZB002", typeof(AggregateException), typeof(MyInnerException))]
public void DoWork()
{
DoInnerWork();
}
private void DoInnerWork()
{
DoSomethingWithExceptions();
}
Im Catch, wo der Fehler-Code gebraucht wird, sucht man den StackTrace ab, findet "DoWork", prüft, welcher der Mappings passt und nimmt ggf. den Fehler-Code.
Die Performance wird sicher keine Preise gewinnen, aber wenn eine Exception soweit ist, dass ein Fehler-Response geschrieben werden muss, stört das auch nicht mehr.
Mir persönlich gefällt, dass sich an der tatsächlichen Implementierung genau nichts ändert und man somit auch keine Seiteneffekte hat. Außerdem muss eine Methode sich einzig und allein um das kümmern, was sie selber aufruft.
Meine Frage ist jetzt: Was haltet Ihr davon?
Gibt es bessere Wege, so eine Anforderung umzusetzen?
Seht Ihr Probleme bei der Idee?
Beste Grüße