Exception: Exception

Inherits:
Object show all
Defined in:
error.c,
error.c

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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#new(msg = nil) ⇒ Exception #exception(msg = nil) ⇒ Exception

Construct a new Exception object, optionally passing in

a message.

Overloads:



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

.exceptionObject

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.

Returns:

  • (Boolean)


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.

Returns:

  • (Boolean)


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);
}

#backtraceArray?

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

Returns:



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_locationsArray?

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().

Returns:



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;
}

#causeException?

Returns the previous exception ($!) at the time this exception was raised. This is useful for wrapping exceptions and retaining the original exception information.

Returns:



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.

Returns:



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.

Returns:



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;
}

#inspectString

Return this exception’s class name and message.

Returns:



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;
}

#messageString

Returns the result of invoking exception.to_s. Normally this returns the exception’s message or name.

Returns:



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.

Returns:



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_sString

Returns exception’s message (or the name of the exception if no message is set).

Returns:



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);
}