Ich kann anscheinend nicht viele Informationen zu benutzerdefinierten Ausnahmeklassen finden.
Was ich weiß
Sie können Ihre benutzerdefinierte Fehlerklasse deklarieren und von ihr erben lassen StandardError
, sodass sie rescue
d sein kann:
class MyCustomError < StandardError
end
Dies ermöglicht es Ihnen, es zu erhöhen, indem Sie:
raise MyCustomError, "A message"
und später erhalten Sie diese Nachricht bei der Rettung
rescue MyCustomError => e
puts e.message # => "A message"
Was ich nicht weiß
Ich möchte meiner Ausnahme einige benutzerdefinierte Felder geben, aber ich möchte das message
Attribut von der übergeordneten Klasse erben . Ich fand heraus , das Lesen zu diesem Thema , das @message
nicht eine Instanzvariable der Ausnahmeklasse, so dass ich besorgt bin , dass mein Erbe wird nicht funktionieren.
Kann mir jemand mehr Details dazu geben? Wie würde ich eine benutzerdefinierte Fehlerklasse mit einem object
Attribut implementieren ? Ist folgendes richtig:
class MyCustomError < StandardError
attr_reader :object
def initialize(message, object)
super(message)
@object = object
end
end
Und dann:
raise MyCustomError.new(anObject), "A message"
bekommen:
rescue MyCustomError => e
puts e.message # => "A message"
puts e.object # => anObject
Wird es funktionieren, und wenn ja, ist dies die richtige Art, Dinge zu tun?
rescue Exception => e
. Es ist breiter als die Standardeinstellung, vonrescue => e
der ausStandardError
alles erfasst wird, einschließlich Strg + C. Ich würde es tunrescue MyCustomError => e
.Antworten:
raise
Setzt die Nachricht bereits so, dass Sie sie nicht an den Konstruktor übergeben müssen:Ich habe ersetzt
rescue Exception
durchrescue MyCustomError
, siehe Warum ist es ein schlechter Stil, Exception => e in Ruby zu retten? .quelle
rescue Exception
, aber warum nichtrescue MyCustomError
?raise MyCustomError, "a message"
ohnenew
"eine Nachricht" nicht gesetzt wird.In Anbetracht dessen, worüber die Ruby-Core-Dokumentation
Exception
, von der alle anderen Fehler erben, aussagt#message
http://ruby-doc.org/core-1.9.3/Exception.html#method-i-message
Ich würde mich für eine Neudefinition
to_s
/to_str
oder den Initialisierer entscheiden. Hier ist ein Beispiel, in dem wir auf meist menschlich lesbare Weise wissen möchten, wann ein externer Dienst etwas nicht getan hat.HINWEIS: In der folgenden zweiten Strategie werden die Rails-Methoden für hübsche Zeichenfolgen verwendet, z. B.
demodualize
, die möglicherweise etwas kompliziert und daher in einer Ausnahme möglicherweise unklug sind. Sie können der Methodensignatur bei Bedarf auch weitere Argumente hinzufügen.#To_s Strategie überschreiben nicht #to_str, es funktioniert anders
Konsolenausgabe
# Initialize Strategy überschreiben
Dies ist die Strategie, die den Implementierungen am nächsten kommt, die ich in Schienen verwendet habe. Wie oben erwähnt, verwendet es das
demodualize
,underscore
undhumanize
ActiveSupport
Methoden. Dies könnte jedoch wie in der vorherigen Strategie leicht entfernt werden.Konsolenausgabe
Demo-Tool
Dies ist eine Demo, die zeigt, wie die oben genannte Implementierung gerettet und übermittelt wird. Die Klasse, die die Ausnahmen auslöst, ist eine gefälschte API für Cloudinary. Legen Sie einfach eine der oben genannten Strategien in Ihre Rails-Konsole ein, gefolgt von dieser.
quelle
Ihre Idee ist richtig, aber die Art, wie Sie sie nennen, ist falsch. Es sollte sein
quelle
raise
Schlüsselwort ist oder so.initialize
zwei Argumente neu definiert .new
übergibt die Argumente aninitialize
.raise(BillRowError.new(:roamingcalls, @index), "Roaming Calls field missing")
. Also ruft erraise
mit zwei Parametern auf: einem neuenBillRowError
Objekt und seiner Nachricht. Ich bin nur verwirrt von der Syntax ... In anderen Tutorials sehe ich das immer so:raise Error, message
raise
. das ist ziemlich flexibel. Das Problem ist, dass Sieinitialize
zwei Argumente definiert und nur eines angegeben haben. Schauen Sie in Ihr Beispiel.BillRowError.new(:roamingcalls, @index)
wird zwei Argumente gegeben.Ich wollte etwas Ähnliches machen. Ich wollte ein Objekt an #new übergeben und die Nachricht basierend auf einer Verarbeitung des übergebenen Objekts festlegen. Folgendes funktioniert.
Beachten Sie, dass
attr_accessor :message
es nicht funktioniert , wenn Sie nicht deklarieren . Wenn Sie das Problem des OP beheben möchten, können Sie die Nachricht auch als zusätzliches Argument übergeben und alles speichern, was Sie möchten. Der entscheidende Teil scheint darin zu bestehen, #message zu überschreiben.quelle