it-swarm.com.de

Wie soll ich zusätzliche Informationen zu einer Ausnahme bereitstellen?

Jedes Mal, wenn ich zusätzliche Informationen zu einer Ausnahme bereitstellen muss, frage ich mich, welcher Weg tatsächlich der richtige Weg ist, dies zu tun.


Für diese Frage habe ich ein Beispiel geschrieben. Nehmen wir an, es gibt eine Klasse, in der wir die Eigenschaft Abbreviation aktualisieren möchten. Aus der Sicht von SOLID) ist es möglicherweise nicht perfekt, aber selbst wenn wir die Worker-Methode über DI mit einem Dienst übergeben würden, würde dieselbe Situation auftreten - eine Ausnahme tritt auf und es gibt keinen Kontext dazu. Zurück zum Beispiel ...

class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Abbreviation { get; set; }
}

Dann gibt es einige Instanzen der Klasse und eine Schleife, in der die Worker-Methode aufgerufen wird. Es kann das StringTooShortException werfen.

var persons =
{
    new Person { Id = 1, Name = "Fo" },
    new Person { Id = 2, Name = "Barbaz" },
}

public IEnumerable<Person> GenerateAbbreviation(IEnumerable<Person> persons)
{
    foreach (var person in persons)
    {
        try
        {
            person.Abbreviation = GenerateAbbreviation(person.Name);
        }
        catch(Exception ex)
        {
            // ?
        }
    }
    // throw AggregateException...
}

public IEnumerable<string> GenerateAbbreviation(string value)
{
    if (value.Length < 5)
    {
        throw new StringTooShortException(value);
    }

    // generate abbreviation
}

Die Frage ist: Wie füge ich das Person oder sein Id (oder irgendetwas anderes) hinzu?


Ich kenne die folgenden drei Techniken:


1 - Verwenden Sie die Eigenschaft Data

Vorteile:

  • einfach zusätzliche Informationen einzustellen
  • erfordert nicht, noch mehr Ausnahmen zu erstellen
  • erfordert kein zusätzliches try/catch

Nachteile:

  • kann nicht einfach in Message integriert werden
  • logger ignorieren dieses Feld und geben es nicht aus
  • erfordert Schlüssel und Casting, da die Werte object sind
  • nicht unveränderlich

Beispiel:

public IEnumerable<Person> GenerateAbbreviation(IEnumerable<Person> persons)
{
    foreach (var person in persons)
    {
        try
        {
            person.Abbreviation = GenerateAbbreviation(person.Name);
        }
        catch(Exception ex)
        {
            ex.Data["PersonId"] = person.Id;
            // collect ex
        }
    }
    // throw AggregateException...
}

2 - Verwenden Sie benutzerdefinierte Eigenschaften

Vorteile:

  • ähnlich der Eigenschaft Data, jedoch stark typisiert
  • einfacher in das Message zu integrieren

Nachteile:

  • erfordert benutzerdefinierte Ausnahmen
  • logger wird sie ignorieren
  • nicht unveränderlich

Beispiel:

public IEnumerable<Person> GenerateAbbreviation(IEnumerable<Person> persons)
{
    foreach (var person in persons)
    {
        try
        {
            person.Abbreviation = GenerateAbbreviation(person.Name);
        }
        catch(Exception ex)
        {
            // not suitable for this exception because 
            // it doesn't have anything in common with the Person
        }
    }
    // throw AggregateException...
}

3 - Schließen Sie die Ausnahme mit einer anderen Ausnahme ab

Vorteile:

  • Message kann auf vorhersehbare Weise formatiert werden
  • logger geben innere Ausnahmen aus
  • unveränderlich

Nachteile:

  • erfordert zusätzliches try/catch
  • erhöht die Verschachtelung
  • erhöht die Tiefe der Ausnahmen

Beispiel:

public IEnumerable<Person> GenerateAbbreviation(IEnumerable<Person> persons)
{
    foreach (var person in persons)
    {
        try
        {
            try
            {
                person.Abbreviation = GenerateAbbreviation(person.Name);
            }
            catch(Exception ex)
            {
                throw new InvalidPersonDataException(person.Id, ex);
            }
        }
        catch(Exception ex)
        {
            // collect ex
        }
    }
    // throw AggregateException...
}

  • Gibt es noch andere Muster?
  • Gibt es bessere Muster?
  • Können Sie Best Practices für alle vorschlagen?
20
t3chb0t

Data FTW .

Dein "Contra":

  • "kann nicht einfach in die Nachricht integriert werden"

-> Für your Ausnahmetypen sollte es einfach genug sein, Message zu überschreiben, damit tutData .. obwohl ich dies nur in Betracht ziehen würde, wenn Data die Nachricht ist .

  • "Logger ignorieren dieses Feld und geben es nicht aus."

Als Beispiel für Nlog googeln ergibt :

Ausnahme Layout Renderer

(...)

Format - Format der Ausgabe. Muss eine durch Kommas getrennte Liste von Ausnahmeeigenschaften sein: Message, Type, ShortType, ToString, Method, StackTrace & Data. Dieser Parameterwert unterscheidet nicht zwischen Groß- und Kleinschreibung. Standard: message

Das scheint also einfach zu konfigurieren zu sein.

  • erfordert Schlüssel und Casting, da Werte Objekt sind

Huh? Legen Sie die Objekte einfach dort ab und stellen Sie sicher, dass sie über eine verwendbare Methode ToString() verfügen.

Außerdem sehe ich kein Problem mit den Schlüsseln. Verwenden Sie einfach eine milde Einzigartigkeit und Sie sind gut.


Haftungsausschluss: Dies ist, was ich sofort aus der Frage ersehen konnte und was ich in 15 Minuten auf Data gegoogelt habe. Ich fand es leicht hilfreich, also habe ich es als Antwort ausgegeben, aber ich habe Data selbst nie verwendet, daher kann es gut sein, dass der Fragesteller hier viel mehr darüber weiß als ich.

6
Martin Ba

Warum wirfst du Ausnahmen? Um sie fangen und behandeln zu lassen.

Wie funktioniert der Fangcode wie, um die Ausnahme zu behandeln? Verwenden der Eigenschaften, die Sie für das Exception-Objekt definieren.

Verwenden Sie niemals die Message-Eigenschaft, um die Ausnahme zu identifizieren oder "Informationen" bereitzustellen, auf die sich ein potenzieller Handler verlassen sollte. Es ist einfach zu volatil und unzuverlässig.

Ich habe die Eigenschaft "Daten" noch nie verwendet, aber sie klingt für mich zu allgemein.

Wenn Sie nicht viele Ausnahmeklassen erstellen, von denen jede einen spezifischen Ausnahmefall identifiziert, woher wissen Sie wenn Sie die Ausnahme abfangen welche "Daten " repräsentiert? (Siehe vorhergehenden Kommentar zu "Nachricht").

2
Phill W.