Exception: Exception
Overview
Class Exception and its subclasses are used to communicate between Kernel#raise and rescue
statements in begin ... end
blocks.
An Exception object carries information about an exception:
-
Its type (the exception’s class).
-
An optional descriptive message.
-
Optional backtrace information.
Some built-in subclasses of Exception have additional methods: e.g., NameError#name.
Defaults
Two Ruby statements have default exception classes:
-
raise
: defaults to RuntimeError. -
rescue
: defaults to StandardError.
Global Variables
When an exception has been raised but not yet handled (in rescue
, ensure
, at_exit
and END
blocks), two global variables are set:
-
$!
contains the current exception. -
$@
contains its backtrace.
Custom Exceptions
To provide additional or alternate information, a program may create custom exception classes that derive from the built-in exception classes.
A good practice is for a library to create a single “generic” exception class (typically a subclass of StandardError or RuntimeError) and have its other exception classes derive from that class. This allows the user to rescue the generic exception, thus catching all exceptions the library may raise even if future versions of the library add new exception subclasses.
For example:
class MyLibrary
class Error < ::StandardError
end
class WidgetError < Error
end
class FrobError < Error
end
end
To handle both MyLibrary::WidgetError and MyLibrary::FrobError the library user can rescue MyLibrary::Error.
Built-In Exception Classes
The built-in subclasses of Exception are:
-
NoMemoryError
-
ScriptError
-
LoadError
-
NotImplementedError
-
SyntaxError
-
-
SecurityError
-
SignalException
-
Interrupt
-
-
StandardError
-
ArgumentError
-
UncaughtThrowError
-
-
EncodingError
-
FiberError
-
IOError
-
EOFError
-
-
IndexError
-
KeyError
-
StopIteration
-
ClosedQueueError
-
-
-
LocalJumpError
-
NameError
-
NoMethodError
-
-
RangeError
-
FloatDomainError
-
-
RegexpError
-
RuntimeError
-
FrozenError
-
-
SystemCallError
-
Errno::*
-
-
ThreadError
-
TypeError
-
ZeroDivisionError
-
-
SystemExit
-
SystemStackError
-
fatal
Direct Known Subclasses
NoMemoryError, ScriptError, SecurityError, SignalException, StandardError, SystemExit, SystemStackError, fatal
Class Method Summary collapse
-
.exception ⇒ Object
call-seq: exc.exception() -> an_exception or exc.
-
.to_tty? ⇒ Boolean
Returns
true
if exception messages will be sent to a tty.
Instance Method Summary collapse
-
#==(obj) ⇒ Boolean
Equality—If obj is not an Exception, returns
false
. -
#backtrace ⇒ Array?
Returns any backtrace associated with the exception.
-
#backtrace_locations ⇒ Array?
Returns any backtrace associated with the exception.
-
#cause ⇒ Exception?
Returns the previous exception ($!) at the time this exception was raised.
-
#detailed_message(highlight: bool, **opt) ⇒ String
Processes a string returned by #message.
-
#exception(*args) ⇒ Object
call-seq: exc.exception() -> an_exception or exc.
-
#full_message(highlight: bool, order: [:top) ⇒ String
Returns formatted string of exception.
-
#initialize(*args) ⇒ Object
constructor
Construct a new Exception object, optionally passing in a message.
-
#inspect ⇒ String
Return this exception’s class name and message.
-
#message ⇒ String
Returns the result of invoking
exception.to_s
. -
#set_backtrace(backtrace) ⇒ Array
Sets the backtrace information associated with
exc
. -
#to_s ⇒ String
Returns exception’s message (or the name of the exception if no message is set).
Constructor Details
#new(msg = nil) ⇒ Exception #exception(msg = nil) ⇒ Exception
Construct a new Exception object, optionally passing in
a message.
1419 1420 1421 1422 1423 1424 1425 1426 |
# File 'error.c', line 1419
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);
}
|
Class Method Details
.exception ⇒ Object
call-seq:
exc.exception([string]) -> an_exception or exc
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
.
.to_tty? ⇒ Boolean
Returns true
if exception messages will be sent to a tty.
1504 1505 1506 1507 1508 |
# File 'error.c', line 1504
static VALUE
exc_s_to_tty_p(VALUE self)
{
return RBOOL(rb_stderr_tty_p());
}
|
Instance Method Details
#==(obj) ⇒ Boolean
Equality—If obj is not an Exception, returns false
. Otherwise, returns true
if exc and obj share same class, messages, and backtrace.
1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 |
# File 'error.c', line 1874
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);
}
|
#backtrace ⇒ Array?
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
In the case no backtrace has been set, nil
is returned
ex = StandardError.new
ex.backtrace
#=> nil
1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 |
# File 'error.c', line 1740
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;
}
|
#backtrace_locations ⇒ Array?
Returns any backtrace associated with the exception. This method is similar to Exception#backtrace, but the backtrace is an array of Thread::Backtrace::Location.
This method is not affected by Exception#set_backtrace().
1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 |
# File 'error.c', line 1788
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;
}
|
#cause ⇒ Exception?
Returns the previous exception ($!) at the time this exception was raised. This is useful for wrapping exceptions and retaining the original exception information.
1853 1854 1855 1856 1857 |
# File 'error.c', line 1853
static VALUE
exc_cause(VALUE exc)
{
return rb_attr_get(exc, id_cause);
}
|
#detailed_message(highlight: bool, **opt) ⇒ String
Processes a string returned by #message.
It may add the class name of the exception to the end of the first line. Also, when highlight
keyword is true, it adds ANSI escape sequences to make the message bold.
If you override this method, it must be tolerant for unknown keyword arguments. All keyword arguments passed to #full_message are delegated to this method.
This method is overridden by did_you_mean and error_highlight to add their information.
A user-defined exception class can also define their own detailed_message
method to add supplemental information. When highlight
is true, it can return a string containing escape sequences, but use widely-supported ones. It is recommended to limit the following codes:
-
Reset (
\e[0m
) -
Bold (
\e[1m
) -
Underline (
\e[4m
) -
Foreground color except white and black
-
Red (
\e[31m
) -
Green (
\e[32m
) -
Yellow (
\e[33m
) -
Blue (
\e[34m
) -
Magenta (
\e[35m
) -
Cyan (
\e[36m
)
-
Use escape sequences carefully even if highlight
is true. Do not use escape sequences to express essential information; the message should be readable even if all escape sequences are ignored.
1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 |
# File 'error.c', line 1656
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, const VALUE emesg, int highlight);
return rb_decorate_message(CLASS_OF(exc), rb_get_message(exc), RTEST(highlight));
}
|
#exception(*args) ⇒ Object
call-seq:
exc.exception([string]) -> an_exception or exc
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
.
1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 |
# File 'error.c', line 1441
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;
}
|
#full_message(highlight: bool, order: [:top) ⇒ String
Returns formatted string of exception. The returned string is formatted using the same format that Ruby uses when printing an uncaught exceptions to stderr.
If highlight is true
the default error handler will send the messages to a tty.
order must be either of :top
or :bottom
, and places the error message and the innermost backtrace come at the top or the bottom.
The default values of these options depend on $stderr
and its tty?
at the timing of a call.
1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 |
# File 'error.c', line 1578
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;
}
|
#inspect ⇒ String
Return this exception’s class name and message.
1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 |
# File 'error.c', line 1677
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;
}
|
#message ⇒ String
Returns the result of invoking exception.to_s
. Normally this returns the exception’s message or name.
1610 1611 1612 1613 1614 |
# File 'error.c', line 1610
static VALUE
exc_message(VALUE exc)
{
return rb_funcallv(exc, idTo_s, 0, 0);
}
|
#set_backtrace(backtrace) ⇒ Array
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 Exception#backtrace.
1832 1833 1834 1835 1836 |
# File 'error.c', line 1832
static VALUE
exc_set_backtrace(VALUE exc, VALUE bt)
{
return rb_ivar_set(exc, id_bt, rb_check_backtrace(bt));
}
|
#to_s ⇒ String
Returns exception’s message (or the name of the exception if no message is set).
1462 1463 1464 1465 1466 1467 1468 1469 |
# File 'error.c', line 1462
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);
}
|