2010-02-11 4 views
12

diese einfache Klasse vor:Wie kann ich strukturierte Ausnahmen von Moose bekommen?

package Foo; 
use Moose; 
has foo => (is => 'rw', isa => 'Int'); 

Und dann diesen Code:

use Try::Tiny; 
use Foo; 
my $f = try { 
    Foo->new(foo => 'Not an Int'); 
} 
catch { 
    warn $_; 
}; 

Der Code stirbt mit einer schönen großen Fehlermeldung über Fehler Typen Einschränkungen.

Ich möchte in der Lage zu extrahieren, welches Attribut fehlgeschlagen (foo), was der Grund war (fehlgeschlagen Typ Einschränkung) und was der Wert übergeben wurde (Not an Int) ohne eine Fehlerzeichenfolge zu analysieren, um die Informationen zu erhalten.

Etwas wie folgt aus:

catch { 
    if($_->isa('MooseX::Exception::TypeConstraint')) { 
     my $attrib = $_->attribute; 
     my $type = $_->type; 
     my $value = $_->bad_value; 

     warn "'$value' is an illegal value for '$attrib'. It should be a $type\n"; 
    } 
    else { 
     warn $_; 
    } 
}; 

Ist das möglich? Gibt es eine MooseX-Distribution, die das möglich macht? Besser noch, gibt es eine Moose-Funktion, die ich vermisst habe, die das möglich macht?

Update: Ich bin besonders interessiert an Typ Einschränkungen, aber andere Moose Fehler wären auch sehr gut. Mir ist auch bewusst, dass ich Objekte mit die werfen kann. Strukturieren von Ausnahmen in Code, den ich schreibe, ist also relativ einfach.

Antwort

4

Ich habe es selbst nicht versucht, aber ich denke, MooseX::Error::Exception::Class könnte das sein, was Sie suchen.

+0

Das ist sehr interessant.Es funktioniert wie MooseX :: Throwable, baut aber auf Exception :: Class auf und definiert die Anfänge einer Ausnahmeklassenhierarchie. Intern analysiert es die Fehlermeldung, um festzustellen, welche Art von Ausnahme ausgelöst werden soll. – daotoad

+0

Leider wurde es für eine Weile nicht aktualisiert und versagt seine Tests ziemlich überall. –

3

Überprüfen Sie MooseX::Throwable, die den error_class Wert in der Metaklasse ersetzt. Der Code sieht jedoch etwas alt aus (Metarole unterstützen jetzt Fehlerklassenrollen), aber die aktuelle Methode sieht so aus, als würde sie immer noch funktionieren.

+0

Das sah wirklich vielversprechend aus, aber die einzigen Attribute, die es hat, sind: stack (der Stack-Trace), previous_exception (falls wir Ausnahmen verschachtelt haben) und message (das "Attribut (foo) nicht ....") . Immer noch geparst die Nachricht. – daotoad

+1

Aye, ich vermute, dass jemand eine echte Exception-Klasse erstellen muss und sie explizit im Fehlerfall (im Core-Code) aufbauen muss, anstatt einfach eine Klasse um die rohen Nachrichten zu konstruieren, die jetzt erstellt werden. Es wäre eine ziemliche Aufgabe, den ganzen Kerncode durchzugehen, um ihn zu ändern, aber ich bin mir sicher, dass viele Leute es dir danken werden! – Ether

+0

oops, ich wollte nicht freiwillig. :) Ich hatte wirklich gehofft, eine schöne RTFM Antwort zu bekommen. So ist das Leben. – daotoad

1

Ich hatte die gleiche Frage vor einem Jahr und fragte am #moose IRC-Kanal. Die Antwort war, dass Moose keine strukturierten Ausnahmen unterstützt.

Es gibt eine allgemeine Übereinstimmung, dass es ein Manko von Moose ist, das behoben werden sollte, aber die Aufgabe, Ausnahmen überall einzuführen, ist mühsam und wurde (afaik) noch nicht ausgeführt.

Der Ansatz in MooseX :: Fehler :: Exception :: Class ist sehr spröde, da es auf die Analyse der Nachrichten von Moose basiert.

Da Sie keine zuverlässigen strukturierten Ausnahmen von Moose erhalten können, sollten Sie die Introspektion verwenden, um jede Ihrer Typabhängigkeiten einzeln zu testen, wenn Sie einen neuen Wert festlegen. Manchmal ist dies ein praktikabler Ansatz.

Btw: beachten Sie, dass es a nasty bug in the way Moose handles composite constraints gibt.

+0

Yeouch! Das ist ein heckuva Bug. Während Exception :: Class interessant aussieht, scheint es mir ** falsch ** zu sein, zwei verschiedene Objektbau-Bibliotheken in einem Projekt zu verwenden. Throwable ist interessant, aber ich denke, Ausnahmen sind einer der Orte, an denen Vererbung sinnvoll ist. Alles, was du wirfst, sollte ** eine Ausnahme sein, statt "Werfbar" (was auch immer das bedeutet ...). Ich bin nicht 100% verkauft, dass die Vererbung * die * richtige Lösung ist. Vielleicht ist die Antwort eine einzelne Ausnahmeklasse mit entsprechenden Attributen. Ich bin mir noch nicht sicher. – daotoad

+0

Dieser Fehler wurde seither geschlossen, es würde erscheinen. –

Verwandte Themen