Exception Handling
Ausnahmen werden in einem begin/end Block abgefangen
begin # code that might raise rescue # handle exception end
Wenn Sie sich innerhalb einer Methode befinden, müssen Sie begin oder end nicht verwenden, es sei denn, Sie möchten den Geltungsbereich abgefangener Ausnahmen einschränken
def my_method # ... rescue # ... end
Dasselbe gilt für eine class, module und block
[0, 1, 2].map do |i| 10 / i rescue ZeroDivisionError nil end #=> [nil, 10, 5]
Sie können die Ausnahme einer lokalen Variable zuweisen, indem Sie => variablen_name am Ende der rescue Zeile verwenden
begin # ... rescue => exception warn exception.message raise # re-raise the current exception end
Standardmäßig werden StandardError und seine Unterklassen abgefangen. Sie können einen bestimmten Satz von Ausnahmeklassen (und deren Unterklassen) abfangen, indem Sie sie nach rescue auflisten
begin # ... rescue ArgumentError, NameError # handle ArgumentError or NameError end
Sie können verschiedene Arten von Ausnahmen auf unterschiedliche Weise abfangen
begin # ... rescue ArgumentError # handle ArgumentError rescue NameError # handle NameError rescue # handle any StandardError end
Die Ausnahme wird von oben nach unten mit dem ersten passenden rescue Abschnitt abgeglichen und nur einmal. Wenn im begin Abschnitt ein ArgumentError ausgelöst wird, wird er nicht im StandardError Abschnitt behandelt.
Sie können abgefangene Ausnahmen erneut versuchen
begin # ... rescue # do something that may change the result of the begin block retry end
Die Ausführung wird am Anfang des begin Blocks fortgesetzt. Seien Sie also vorsichtig, um eine Endlosschleife zu vermeiden.
Innerhalb eines rescue Blocks ist die einzige gültige Stelle für retry, alle anderen Verwendungen lösen einen SyntaxError aus. Wenn Sie eine Blockiteration wiederholen möchten, verwenden Sie redo. Weitere Details finden Sie unter Kontrollausdrücke.
Um immer Code auszuführen, unabhängig davon, ob eine Ausnahme ausgelöst wurde oder nicht, verwenden Sie ensure
begin # ... rescue # ... ensure # this always runs BUT does not implicitly return the last evaluated statement. end
Sie können auch Code ausführen, wenn keine Ausnahme ausgelöst wird
begin # ... rescue # ... else # this runs only when no exception was raised AND return the last evaluated statement ensure # this always runs. # It is evaluated after the evaluation of either the `rescue` or the `else` block. # It will not return implicitly. end
NB: Ohne explizites return im ensure Block gibt der begin/end Block die zuletzt ausgewertete Anweisung zurück, bevor in den ensure Block eingetreten wird.