class Exception
Die Klasse Exception und ihre Unterklassen werden verwendet, um anzuzeigen, dass ein Fehler oder ein anderes Problem aufgetreten ist und möglicherweise behandelt werden muss. Siehe Ausnahmen.
Ein Exception-Objekt trägt bestimmte Informationen
-
Der Typ (die Klasse der Ausnahme), üblicherweise
StandardError,RuntimeErroroder eine Unterklasse von einer der beiden; siehe Hierarchie der integrierten Ausnahme-Klassen. -
Eine optionale beschreibende Nachricht; siehe Methoden
::new,message. -
Optionale Backtrace-Informationen; siehe Methoden
backtrace,backtrace_locations,set_backtrace. -
Eine optionale Ursache; siehe Methode
cause.
Hierarchie der integrierten Ausnahme-Klassen
Die Hierarchie der integrierten Unterklassen der Klasse Exception
-
-
-
Errno(und seine Unterklassen, die Systemfehler darstellen)
-
Öffentliche Klassenmethoden
Gibt ein Ausnahmeobjekt derselben Klasse wie self zurück; nützlich zum Erstellen einer ähnlichen Ausnahme, aber mit einer anderen Nachricht.
Mit message nil wird self zurückgegeben
x0 = StandardError.new('Boom') # => #<StandardError: Boom> x1 = x0.exception # => #<StandardError: Boom> x0.__id__ == x1.__id__ # => true
Mit einem string-konvertierbaren Objekt message (auch dem gleichen wie die ursprüngliche Nachricht) wird ein neues Ausnahmeobjekt zurückgegeben, dessen Klasse dieselbe wie self ist und dessen Nachricht die gegebene message ist
x1 = x0.exception('Boom') # => #<StandardError: Boom> x0..equal?(x1) # => false
Source
# File ext/json/lib/json/add/exception.rb, line 9 def self.json_create(object) result = new(object['m']) result.set_backtrace object['b'] result end
Siehe as_json.
Source
static VALUE
exc_initialize(int argc, VALUE *argv, VALUE exc)
{
VALUE arg;
arg = (!rb_check_arity(argc, 0, 1) ? Qnil : argv[0]);
return exc_init(exc, arg);
}
Gibt ein neues Ausnahmeobjekt zurück.
Die angegebene message sollte ein string-konvertierbares Objekt sein; siehe Methode message; wenn nicht angegeben, ist die Nachricht der Klassenname der neuen Instanz (was der Name einer Unterklasse sein kann)
Beispiele
Exception.new # => #<Exception: Exception> LoadError.new # => #<LoadError: LoadError> # Subclass of Exception. Exception.new('Boom') # => #<Exception: Boom>
Source
static VALUE
exc_s_to_tty_p(VALUE self)
{
return RBOOL(rb_stderr_tty_p());
}
Gibt true zurück, wenn Ausnahme-Nachrichten an ein Terminalgerät gesendet werden.
Öffentliche Instanzmethoden
Source
static VALUE
exc_equal(VALUE exc, VALUE obj)
{
VALUE mesg, backtrace;
if (exc == obj) return Qtrue;
if (rb_obj_class(exc) != rb_obj_class(obj)) {
int state;
obj = rb_protect(try_convert_to_exception, obj, &state);
if (state || UNDEF_P(obj)) {
rb_set_errinfo(Qnil);
return Qfalse;
}
if (rb_obj_class(exc) != rb_obj_class(obj)) return Qfalse;
mesg = rb_check_funcall(obj, id_message, 0, 0);
if (UNDEF_P(mesg)) return Qfalse;
backtrace = rb_check_funcall(obj, id_backtrace, 0, 0);
if (UNDEF_P(backtrace)) return Qfalse;
}
else {
mesg = rb_attr_get(obj, id_mesg);
backtrace = exc_backtrace(obj);
}
if (!rb_equal(rb_attr_get(exc, id_mesg), mesg))
return Qfalse;
return rb_equal(exc_backtrace(exc), backtrace);
}
Source
# File ext/json/lib/json/add/exception.rb, line 29 def as_json(*) { JSON.create_id => self.class.name, 'm' => message, 'b' => backtrace, } end
Die Methoden Exception#as_json und Exception.json_create können verwendet werden, um ein Exception-Objekt zu serialisieren und zu deserialisieren; siehe Marshal.
Die Methode Exception#as_json serialisiert self und gibt einen 2-elementigen Hash zurück, der self repräsentiert
require 'json/add/exception' x = Exception.new('Foo').as_json # => {"json_class"=>"Exception", "m"=>"Foo", "b"=>nil}
Die Methode JSON.create deserialisiert einen solchen Hash und gibt ein Exception-Objekt zurück
Exception.json_create(x) # => #<Exception: Foo>
Source
static VALUE
exc_backtrace(VALUE exc)
{
VALUE obj;
obj = rb_attr_get(exc, id_bt);
if (rb_backtrace_p(obj)) {
obj = rb_backtrace_to_str_ary(obj);
/* rb_ivar_set(exc, id_bt, obj); */
}
return obj;
}
Gibt den Backtrace (die Liste der Code-Positionen, die zu der Ausnahme geführt haben) als Array von Strings zurück.
Beispiel (angenommen, der Code ist in der Datei namens t.rb gespeichert)
def division(numerator, denominator) numerator / denominator end begin division(1, 0) rescue => ex p ex.backtrace # ["t.rb:2:in 'Integer#/'", "t.rb:2:in 'Object#division'", "t.rb:6:in '<main>'"] loc = ex.backtrace.first p loc.class # String end
Der von dieser Methode zurückgegebene Wert kann beim Auslösen (siehe Kernel#raise) oder während der zwischenzeitlichen Behandlung durch set_backtrace angepasst werden.
Siehe auch backtrace_locations, das denselben Wert als strukturierte Objekte bereitstellt. (Beachten Sie jedoch, dass zwei Werte möglicherweise nicht übereinstimmen, wenn Backtraces manuell angepasst werden.)
Siehe Backtraces.
Source
static VALUE
exc_backtrace_locations(VALUE exc)
{
VALUE obj;
obj = rb_attr_get(exc, id_bt_locations);
if (!NIL_P(obj)) {
obj = rb_backtrace_to_location_ary(obj);
}
return obj;
}
Gibt den Backtrace (die Liste der Code-Positionen, die zu der Ausnahme geführt haben) als Array von Thread::Backtrace::Location-Instanzen zurück.
Beispiel (angenommen, der Code ist in der Datei namens t.rb gespeichert)
def division(numerator, denominator) numerator / denominator end begin division(1, 0) rescue => ex p ex.backtrace_locations # ["t.rb:2:in 'Integer#/'", "t.rb:2:in 'Object#division'", "t.rb:6:in '<main>'"] loc = ex.backtrace_locations.first p loc.class # Thread::Backtrace::Location p loc.path # "t.rb" p loc.lineno # 2 p loc.label # "Integer#/" end
Der von dieser Methode zurückgegebene Wert kann beim Auslösen (siehe Kernel#raise) oder während der zwischenzeitlichen Behandlung durch set_backtrace angepasst werden.
Siehe auch backtrace, das denselben Wert als Array von Strings bereitstellt. (Beachten Sie jedoch, dass zwei Werte möglicherweise nicht übereinstimmen, wenn Backtraces manuell angepasst werden.)
Siehe Backtraces.
Source
static VALUE
exc_cause(VALUE exc)
{
return rb_attr_get(exc, id_cause);
}
Gibt den vorherigen Wert der globalen Variablen $! zurück, der nil sein kann (siehe Globale Variablen)
begin raise('Boom 0') rescue => x0 puts "Exception: #{x0}; $!: #{$!}; cause: #{x0.cause.inspect}." begin raise('Boom 1') rescue => x1 puts "Exception: #{x1}; $!: #{$!}; cause: #{x1.cause}." begin raise('Boom 2') rescue => x2 puts "Exception: #{x2}; $!: #{$!}; cause: #{x2.cause}." end end end
Ausgabe
Exception: Boom 0; $!: Boom 0; cause: nil. Exception: Boom 1; $!: Boom 1; cause: Boom 0. Exception: Boom 2; $!: Boom 2; cause: Boom 1.
Source
static VALUE
exc_detailed_message(int argc, VALUE *argv, VALUE exc)
{
VALUE opt;
rb_scan_args(argc, argv, "0:", &opt);
VALUE highlight = check_highlight_keyword(opt, 0);
extern VALUE rb_decorate_message(const VALUE eclass, VALUE emesg, int highlight);
return rb_decorate_message(CLASS_OF(exc), rb_get_message(exc), RTEST(highlight));
}
Gibt den Nachrichtentext mit Erweiterungen zurück
-
Enthält den Namen der Ausnahme-Klasse in der ersten Zeile.
-
Wenn der Wert des Schlüsselworts
highlighttrueist, werden fette und unterstrichene ANSI-Codes (siehe unten) zur Verbesserung der Darstellung der Nachricht enthalten.
Beispiele
begin 1 / 0 rescue => x p x.message p x.detailed_message # Class name added. p x.detailed_message(highlight: true) # Class name, bolding, and underlining added. end
Ausgabe
"divided by 0" "divided by 0 (ZeroDivisionError)" "\e[1mdivided by 0 (\e[1;4mZeroDivisionError\e[m\e[1m)\e[m"
Diese Methode wird von einigen Gems in der Ruby-Standardbibliothek überschrieben, um Informationen hinzuzufügen
Eine überschreibende Methode muss tolerant gegenüber übergebenen Schlüsselwortargumenten sein, die enthalten können (aber nicht darauf beschränkt sind)
-
:highlight. -
:did_you_mean. -
:error_highlight. -
:syntax_suggest.
Eine überschreibende Methode sollte auch vorsichtig mit ANSI-Code-Verbesserungen sein; siehe Nachrichten.
Source
static VALUE
exc_exception(int argc, VALUE *argv, VALUE self)
{
VALUE exc;
argc = rb_check_arity(argc, 0, 1);
if (argc == 0) return self;
if (argc == 1 && self == argv[0]) return self;
exc = rb_obj_clone(self);
rb_ivar_set(exc, id_mesg, argv[0]);
return exc;
}
Gibt ein Ausnahmeobjekt derselben Klasse wie self zurück; nützlich zum Erstellen einer ähnlichen Ausnahme, aber mit einer anderen Nachricht.
Mit message nil wird self zurückgegeben
x0 = StandardError.new('Boom') # => #<StandardError: Boom> x1 = x0.exception # => #<StandardError: Boom> x0.__id__ == x1.__id__ # => true
Mit einem string-konvertierbaren Objekt message (auch dem gleichen wie die ursprüngliche Nachricht) wird ein neues Ausnahmeobjekt zurückgegeben, dessen Klasse dieselbe wie self ist und dessen Nachricht die gegebene message ist
x1 = x0.exception('Boom') # => #<StandardError: Boom> x0..equal?(x1) # => false
Source
static VALUE
exc_full_message(int argc, VALUE *argv, VALUE exc)
{
VALUE opt, str, emesg, errat;
VALUE highlight, order;
rb_scan_args(argc, argv, "0:", &opt);
highlight = check_highlight_keyword(opt, 1);
order = check_order_keyword(opt);
{
if (NIL_P(opt)) opt = rb_hash_new();
rb_hash_aset(opt, sym_highlight, highlight);
}
str = rb_str_new2("");
errat = rb_get_backtrace(exc);
emesg = rb_get_detailed_message(exc, opt);
rb_error_write(exc, emesg, errat, str, opt, highlight, order);
return str;
}
Gibt eine erweiterte Nachricht zurück
-
Enthält den Namen der Ausnahme-Klasse.
-
Wenn der Wert des Schlüsselworts
highlighttrue ist (nichtniloderfalse), werden fette ANSI-Codes (siehe unten) zur Verbesserung der Darstellung der Nachricht enthalten. -
Enthält den Backtrace
-
Wenn der Wert des Schlüsselworts
order:top(Standard) ist, werden die Fehlermeldung und der innerste Backtrace-Eintrag zuerst aufgelistet. -
Wenn der Wert des Schlüsselworts
order:bottomist, werden die Fehlermeldung und der innerste Eintrag zuletzt aufgelistet.
-
Beispiel
def baz begin 1 / 0 rescue => x pp x.message pp x.full_message(highlight: false).split("\n") pp x.full_message.split("\n") end end def bar; baz; end def foo; bar; end foo
Ausgabe
"divided by 0" ["t.rb:3:in 'Integer#/': divided by 0 (ZeroDivisionError)", "\tfrom t.rb:3:in 'Object#baz'", "\tfrom t.rb:10:in 'Object#bar'", "\tfrom t.rb:11:in 'Object#foo'", "\tfrom t.rb:12:in '<main>'"] ["t.rb:3:in 'Integer#/': \e[1mdivided by 0 (\e[1;4mZeroDivisionError\e[m\e[1m)\e[m", "\tfrom t.rb:3:in 'Object#baz'", "\tfrom t.rb:10:in 'Object#bar'", "\tfrom t.rb:11:in 'Object#foo'", "\tfrom t.rb:12:in '<main>'"]
Eine überschreibende Methode sollte vorsichtig mit ANSI-Code-Verbesserungen sein; siehe Nachrichten.
Source
static VALUE
exc_inspect(VALUE exc)
{
VALUE str, klass;
klass = CLASS_OF(exc);
exc = rb_obj_as_string(exc);
if (RSTRING_LEN(exc) == 0) {
return rb_class_name(klass);
}
str = rb_str_buf_new2("#<");
klass = rb_class_name(klass);
rb_str_buf_append(str, klass);
if (RTEST(rb_str_include(exc, rb_str_new2("\n")))) {
rb_str_catf(str, ":%+"PRIsVALUE, exc);
}
else {
rb_str_buf_cat(str, ": ", 2);
rb_str_buf_append(str, exc);
}
rb_str_buf_cat(str, ">", 1);
return str;
}
Gibt eine String-Repräsentation von self zurück.
x = RuntimeError.new('Boom') x.inspect # => "#<RuntimeError: Boom>" x = RuntimeError.new x.inspect # => "#<RuntimeError: RuntimeError>"
Source
static VALUE
exc_message(VALUE exc)
{
return rb_funcallv(exc, idTo_s, 0, 0);
}
Gibt to_s zurück.
Siehe Nachrichten.
Source
static VALUE
exc_set_backtrace(VALUE exc, VALUE bt)
{
VALUE btobj = rb_location_ary_to_backtrace(bt);
if (RTEST(btobj)) {
rb_ivar_set(exc, id_bt, btobj);
rb_ivar_set(exc, id_bt_locations, btobj);
return bt;
}
else {
return rb_ivar_set(exc, id_bt, rb_check_backtrace(bt));
}
}
Setzt den Backtrace-Wert für self; gibt den gegebenen value zurück.
Der value kann sein
-
ein Array von
Thread::Backtrace::Location; -
ein Array von
String-Instanzen; -
eine einzelne
String-Instanz; oder -
nil.
Die Verwendung eines Arrays von Thread::Backtrace::Location ist die konsistenteste Option: Sie setzt sowohl backtrace als auch backtrace_locations. Sie sollte bevorzugt werden, wenn möglich. Das passende Array von Speicherorten kann von Kernel#caller_locations bezogen, von einer anderen Ausnahme kopiert oder einfach auf das angepasste Ergebnis der backtrace_locations der aktuellen Ausnahme gesetzt werden.
require 'json' def parse_payload(text) JSON.parse(text) # test.rb, line 4 rescue JSON::ParserError => ex ex.set_backtrace(ex.backtrace_locations[2...]) raise end parse_payload('{"wrong: "json"') # test.rb:4:in 'Object#parse_payload': unexpected token at '{"wrong: "json"' (JSON::ParserError) # # An error points to the body of parse_payload method, # hiding the parts of the backtrace related to the internals # of the "json" library # The error has both #backtace and #backtrace_locations set # consistently: begin parse_payload('{"wrong: "json"') rescue => ex p ex.backtrace # ["test.rb:4:in 'Object#parse_payload'", "test.rb:20:in '<main>'"] p ex.backtrace_locations # ["test.rb:4:in 'Object#parse_payload'", "test.rb:20:in '<main>'"] end
Wenn der gewünschte Stapel von Speicherorten nicht verfügbar ist und von Grund auf neu aufgebaut werden soll, kann ein Array von Strings oder ein einzelner String verwendet werden. In diesem Fall wird nur backtrace beeinflusst.
def parse_payload(text) JSON.parse(text) rescue JSON::ParserError => ex ex.set_backtrace(["dsl.rb:34", "framework.rb:1"]) # The error have the new value in #backtrace: p ex.backtrace # ["dsl.rb:34", "framework.rb:1"] # but the original one in #backtrace_locations p ex.backtrace_locations # [".../json/common.rb:221:in 'JSON::Ext::Parser.parse'", ...] end parse_payload('{"wrong: "json"')
Das Aufrufen von set_backtrace mit nil löscht backtrace, beeinflusst aber nicht backtrace_locations
def parse_payload(text) JSON.parse(text) rescue JSON::ParserError => ex ex.set_backtrace(nil) p ex.backtrace # nil p ex.backtrace_locations # [".../json/common.rb:221:in 'JSON::Ext::Parser.parse'", ...] end parse_payload('{"wrong: "json"')
Beim erneuten Auslösen einer solchen Ausnahme werden sowohl backtrace als auch backtrace_locations auf den Ort des erneuten Auslösens gesetzt.
def parse_payload(text) JSON.parse(text) rescue JSON::ParserError => ex ex.set_backtrace(nil) raise # test.rb, line 7 end begin parse_payload('{"wrong: "json"') rescue => ex p ex.backtrace # ["test.rb:7:in 'Object#parse_payload'", "test.rb:11:in '<main>'"] p ex.backtrace_locations # ["test.rb:7:in 'Object#parse_payload'", "test.rb:11:in '<main>'"] end
Siehe Backtraces.
Source
# File ext/json/lib/json/add/exception.rb, line 46 def to_json(*args) as_json.to_json(*args) end
Gibt einen JSON-String zurück, der self repräsentiert
require 'json/add/exception' puts Exception.new('Foo').to_json
Ausgabe
{"json_class":"Exception","m":"Foo","b":null}
Source
static VALUE
exc_to_s(VALUE exc)
{
VALUE mesg = rb_attr_get(exc, idMesg);
if (NIL_P(mesg)) return rb_class_name(CLASS_OF(exc));
return rb_String(mesg);
}
Gibt eine String-Repräsentation von self zurück.
x = RuntimeError.new('Boom') x.to_s # => "Boom" x = RuntimeError.new x.to_s # => "RuntimeError"