Suche…


Bemerkungen

Eine Ausnahme ist ein Objekt, das das Auftreten einer Ausnahmebedingung darstellt. Mit anderen Worten, es zeigt an, dass etwas schief gelaufen ist.

In Ruby werden Ausnahmen oft als Fehler bezeichnet . Dies liegt daran, dass die Basis- Exception Klasse als Exception -Objektelement der obersten Ebene vorhanden ist, aber benutzerdefinierte Ausführungsausnahmen sind im Allgemeinen StandardError oder Nachkommen.

Ausnahme auslösen

Um eine Exception Kernel#raise verwenden Sie Kernel#raise übergeben Sie die Exception-Klasse und / oder die Nachricht:

raise StandardError # raises a StandardError.new
raise StandardError, "An error" # raises a StandardError.new("An error")

Sie können auch einfach eine Fehlermeldung übergeben. In diesem Fall wird die Nachricht in einen RuntimeError :

raise "An error" # raises a RuntimeError.new("An error")

Hier ist ein Beispiel:

def hello(subject)
  raise ArgumentError, "`subject` is missing" if subject.to_s.empty?
  puts "Hello #{subject}"
end

hello # => ArgumentError: `subject` is missing
hello("Simone") # => "Hello Simone"

Erstellen eines benutzerdefinierten Ausnahmetyps

Eine benutzerdefinierte Ausnahme ist jede Klasse, die Exception oder eine Unterklasse von Exception .

Im Allgemeinen sollten Sie StandardError oder einen Nachkommen immer erweitern. Die Exception bezieht sich normalerweise auf Fehler der virtuellen Maschine oder des Systems. Wenn Sie sie retten, kann eine erzwungene Unterbrechung nicht wie erwartet funktionieren.

# Defines a new custom exception called FileNotFound
class FileNotFound < StandardError
end

def read_file(path)
  File.exist?(path) || raise(FileNotFound, "File #{path} not found")
  File.read(path)
end

read_file("missing.txt")  #=> raises FileNotFound.new("File `missing.txt` not found")
read_file("valid.txt")    #=> reads and returns the content of the file

Es ist üblich, Ausnahmen zu benennen, indem am Ende das Suffix " Error hinzugefügt wird:

  • ConnectionError
  • DontPanicError

Wenn jedoch der Fehler selbsterklärend ist, brauchen Sie nicht den hinzufügen Error Suffix da wäre überflüssig:

  • FileNotFound vs FileNotFoundError
  • DatabaseExploded vs DatabaseExplodedError

Behandlung einer Ausnahme

Verwenden Sie den begin/rescue , um eine Ausnahme abzufangen (Rettung), und behandeln Sie sie:

begin
  # an execution that may fail
rescue
  # something to execute in case of failure
end

Eine rescue ist analog zu einem catch Block in einer geschweiften Klammer wie C # oder Java.

Eine bloße rescue wie diese rettet StandardError .

Anmerkung: Achten Sie darauf, dass Sie anstelle des Standard- StandardError keine Exception fangen. Die Exception Klasse enthält SystemExit und NoMemoryError sowie andere schwerwiegende Ausnahmen, die Sie normalerweise nicht abfangen möchten. Erwägen Sie stattdessen immer StandardError (die Standardeinstellung).

Sie können auch die Ausnahmeklasse angeben, die gerettet werden soll:

begin
  # an excecution that may fail
rescue CustomError
  # something to execute in case of CustomError
  # or descendant
end

Diese Rettungsklausel fängt keine Ausnahme ab, die kein CustomError .

Sie können die Ausnahme auch in einer bestimmten Variablen speichern:

begin
  # an excecution that may fail
rescue CustomError => error
  # error contains the exception
  puts error.message # provide human-readable details about what went wrong.
  puts error.backtrace.inspect # return an array of strings that represent the call stack
end

Wenn Sie eine Ausnahme nicht behandelt haben, können Sie sie jederzeit in einem Rettungsblock auslösen.

begin
   #here goes your code
rescue => e
    #failed to handle 
    raise e
end

Wenn Sie Ihr wiederholen möchten begin Block, rufen retry :

begin
   #here goes your code
rescue StandardError => e
   #for some reason you want to retry you code
   retry
end

Sie können in einer Schleife stecken bleiben, wenn Sie bei jeder Wiederholung eine Ausnahme feststellen. Um dies zu vermeiden, beschränken Sie Ihr retry_count auf eine bestimmte Anzahl von Versuchen.

retry_count = 0
begin
      # an excecution that may fail
rescue
    if retry_count < 5
        retry_count = retry_count + 1
        retry
    else
        #retry limit exceeds, do something else
    end

Sie können auch einen else Block oder einen ensure bereitstellen. Ein else Block wird ausgeführt, wenn der begin Block ohne Auslösung einer Ausnahme abgeschlossen ist. Ein ensure wird immer ausgeführt. Ein ensure ist analog zu einem finally Block in einer geschweiften Klammer wie C # oder Java.

begin
  # an execution that may fail
rescue
  # something to execute in case of failure
else
  # something to execute in case of success
ensure
  # something to always execute
end

Wenn Sie sich in einem def , module oder class Block befinden, müssen Sie die begin-Anweisung nicht verwenden.

def foo
    ...
rescue
    ...
end

Behandlung mehrerer Ausnahmen

Sie können mehrere Fehler in derselben rescue :

begin
  # an execution that may fail
rescue FirstError, SecondError => e
  # do something if a FirstError or SecondError occurs
end

Sie können auch mehrere rescue hinzufügen:

begin
  # an execution that may fail
rescue FirstError => e
  # do something if a FirstError occurs
rescue SecondError => e
  # do something if a SecondError occurs
rescue => e
  # do something if a StandardError occurs
end

Die Reihenfolge der rescue ist relevant: Die erste Übereinstimmung ist die ausgeführte. Wenn Sie also StandardError als erste Bedingung setzen und alle Ihre Ausnahmen von StandardError erben, werden die anderen rescue niemals ausgeführt.

begin
  # an execution that may fail
rescue => e
  # this will swallow all the errors
rescue FirstError => e
  # do something if a FirstError occurs
rescue SecondError => e
  # do something if a SecondError occurs
end

Einige Blöcke haben implizite Ausnahmebehandlung wie def , class und module . Mit diesen Blöcken können Sie die begin Anweisung überspringen.

def foo
    ...
rescue CustomError
    ...
ensure
    ...
end

Hinzufügen von Informationen zu (benutzerdefinierten) Ausnahmen

Es kann hilfreich sein, zusätzliche Informationen mit einer Ausnahme hinzuzufügen, z. B. zu Protokollierungszwecken oder zur bedingten Behandlung, wenn die Ausnahme abgefangen wird:

class CustomError < StandardError
  attr_reader :safe_to_retry

  def initialize(safe_to_retry = false, message = 'Something went wrong')
    @safe_to_retry = safe_to_retry
    super(message)
  end
end

Ausnahme auslösen:

raise CustomError.new(true)

Die Ausnahme abfangen und auf die zusätzlichen Informationen zugreifen:

begin
  # do stuff
rescue CustomError => e
  retry if e.safe_to_retry
end


Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow