Descendants of class Exception are used to
communicate between Kernel#raise
and rescue
statements in begin ... end
blocks. Exception objects carry information about the
exception – its type (the exception’s class name), an optional descriptive
string, and optional traceback information. Exception subclasses may add additional
information like NameError#name.
Programs may make subclasses of Exception,
typically of StandardError or RuntimeError, to provide custom classes and
add additional information. See the subclass list below for defaults for
raise
and rescue
.
When an exception has been raised but not yet handled (in
rescue
, ensure
, at_exit
and
END
blocks) the global variable $!
will contain
the current exception and $@
contains the current exception’s
backtrace.
It is recommended that a library should have one subclass of StandardError or RuntimeError and have specific exception types inherit from it. This allows the user to rescue a generic exception type to catch all exceptions the library may raise even if future versions of the library add new exception subclasses.
For example:
class MyLibrary class Error < RuntimeError end class WidgetError < Error end class FrobError < Error end end
To handle both WidgetError and FrobError the library user can rescue MyLibrary::Error.
The built-in subclasses of Exception are:
StandardError -- default for
rescue
fatal – impossible to rescue
With no argument, or if the argument is the same as the receiver, return
the receiver. Otherwise, create a new exception object of the same class as
the receiver, but with a message equal to string.to_str
.
Construct a new Exception object, optionally passing in a message.
static VALUE exc_initialize(int argc, VALUE *argv, VALUE exc) { VALUE arg; rb_scan_args(argc, argv, "01", &arg); rb_iv_set(exc, "mesg", arg); rb_iv_set(exc, "bt", Qnil); return exc; }
Equality—If obj is not an Exception
, returns
false
. Otherwise, returns true
if exc
and obj share same class, messages, and backtrace.
static VALUE exc_equal(VALUE exc, VALUE obj) { VALUE mesg, backtrace; ID id_mesg; if (exc == obj) return Qtrue; CONST_ID(id_mesg, "mesg"); if (rb_obj_class(exc) != rb_obj_class(obj)) { int status = 0; ID id_message, id_backtrace; CONST_ID(id_message, "message"); CONST_ID(id_backtrace, "backtrace"); obj = rb_protect(try_convert_to_exception, obj, &status); if (status || obj == Qundef) { 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 (mesg == Qundef) return Qfalse; backtrace = rb_check_funcall(obj, id_backtrace, 0, 0); if (backtrace == Qundef) 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; if (!rb_equal(exc_backtrace(exc), backtrace)) return Qfalse; return Qtrue; }
Returns any backtrace associated with the exception. The backtrace is an array of strings, each containing either “filename:lineNo: in `method”‘ or “filename:lineNo.”
def a raise "boom" end def b a() end begin b() rescue => detail print detail.backtrace.join("\n") end
produces:
prog.rb:2:in `a' prog.rb:6:in `b' prog.rb:10
static VALUE exc_backtrace(VALUE exc) { ID bt; VALUE obj; CONST_ID(bt, "bt"); obj = rb_attr_get(exc, bt); if (rb_backtrace_p(obj)) { obj = rb_backtrace_to_str_ary(obj); /* rb_iv_set(exc, "bt", obj); */ } return obj; }
With no argument, or if the argument is the same as the receiver, return
the receiver. Otherwise, create a new exception object of the same class as
the receiver, but with a message equal to string.to_str
.
static VALUE exc_exception(int argc, VALUE *argv, VALUE self) { VALUE exc; if (argc == 0) return self; if (argc == 1 && self == argv[0]) return self; exc = rb_obj_clone(self); exc_initialize(argc, argv, exc); return exc; }
Return this exception’s class name and message
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_str_dup(rb_class_name(klass)); } str = rb_str_buf_new2("#<"); klass = rb_class_name(klass); rb_str_buf_append(str, klass); rb_str_buf_cat(str, ": ", 2); rb_str_buf_append(str, exc); rb_str_buf_cat(str, ">", 1); return str; }
Returns the result of invoking exception.to_s
. Normally this
returns the exception’s message or name. By supplying a to_str method,
exceptions are agreeing to be used where Strings are expected.
static VALUE exc_message(VALUE exc) { return rb_funcall(exc, rb_intern("to_s"), 0, 0); }
Sets the backtrace information associated with exc
. The
backtrace
must be an array of String
objects or a single String in the format
described in #backtrace.
static VALUE exc_set_backtrace(VALUE exc, VALUE bt) { return rb_iv_set(exc, "bt", rb_check_backtrace(bt)); }
Returns exception’s message (or the name of the exception if no message is set).
static VALUE exc_to_s(VALUE exc) { VALUE mesg = rb_attr_get(exc, rb_intern("mesg")); VALUE r = Qnil; if (NIL_P(mesg)) return rb_class_name(CLASS_OF(exc)); r = rb_String(mesg); return r; }
Commenting is here to help enhance the documentation. For example, sample code, or clarification of the documentation.
If you are posting code samples in your comments, please wrap them in "<pre><code class="ruby" > ... </code></pre>" markup in order to get syntax highlighting.
If you have questions about Ruby or the documentation, please post to one of the Ruby mailing lists. You will get better, faster, help that way.
If you wish to post a correction of the docs, please do so, but also file a bug report so that it can be corrected for the next release. Thank you.