class Exception

Class Exception and its subclasses are used to indicate that an error or other problem has occurred, and may need to be handled. See Exceptions.

An Exception object carries certain information:

Built-In Exception Class Hierarchy

The hierarchy of built-in subclasses of class Exception:

Public Class Methods

exception(message = nil) → self or new_exception

Returns an exception object of the same class as self; useful for creating a similar exception, but with a different message.

With message nil, returns self:

x0 = StandardError.new('Boom') # => #<StandardError: Boom>
x1 = x0.exception              # => #<StandardError: Boom>
x0.__id__ == x1.__id__         # => true

With string-convertible object message (even the same as the original message), returns a new exception object whose class is the same as self, and whose message is the given message:

x1 = x0.exception('Boom') # => #<StandardError: Boom>
x0..equal?(x1)            # => false
new(message = nil) → exception click to toggle source

Returns a new exception object.

The given message should be a string-convertible object; see method message; if not given, the message is the class name of the new instance (which may be the name of a subclass):

Examples:

Exception.new         # => #<Exception: Exception>
LoadError.new         # => #<LoadError: LoadError> # Subclass of Exception.
Exception.new('Boom') # => #<Exception: Boom>
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);
}
to_tty? → true or false click to toggle source

Returns true if exception messages will be sent to a terminal device.

static VALUE
exc_s_to_tty_p(VALUE self)
{
    return RBOOL(rb_stderr_tty_p());
}

Public Instance Methods

self == object → true or false click to toggle source

Returns whether object is the same class as self and its message and backtrace are equal to those of self.

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 or nil click to toggle source

Returns a backtrace value for self; the returned value depends on the form of the stored backtrace value:

  • Array of Thread::Backtrace::Location objects: returns the array of strings given by Exception#backtrace_locations.map {|loc| loc.to_s }. This is the normal case, where the backtrace value was stored by Kernel#raise.

  • Array of strings: returns that array. This is the unusual case, where the backtrace value was explicitly stored as an array of strings.

  • nil: returns nil.

Example:

begin
  1 / 0
rescue => x
  x.backtrace.take(2)
end
# => ["(irb):132:in `/'", "(irb):132:in `<top (required)>'"]

see Backtraces.

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 or nil click to toggle source

Returns a backtrace value for self; the returned value depends on the form of the stored backtrace value:

Example:

begin
  1 / 0
rescue => x
  x.backtrace_locations.take(2)
end
# => ["(irb):150:in `/'", "(irb):150:in `<top (required)>'"]

See Backtraces.

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 or nil click to toggle source

Returns the previous value of global variable $!, which may be nil (see Global Variables):

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

Output:

Exception: Boom 0;  $!: Boom 0;  cause: nil.
Exception: Boom 1;  $!: Boom 1;  cause: Boom 0.
Exception: Boom 2;  $!: Boom 2;  cause: Boom 1.
static VALUE
exc_cause(VALUE exc)
{
    return rb_attr_get(exc, id_cause);
}
detailed_message(highlight: false, **kwargs) → string click to toggle source

Returns the message string with enhancements:

  • Includes the exception class name in the first line.

  • If the value of keyword highlight is true, includes bolding and underlining ANSI codes (see below) to enhance the appearance of the message.

Examples:

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

Output:

"divided by 0"
"divided by 0 (ZeroDivisionError)"
"\e[1mdivided by 0 (\e[1;4mZeroDivisionError\e[m\e[1m)\e[m"

This method is overridden by some gems in the Ruby standard library to add information:

  • DidYouMean::Correctable#detailed_message.

  • ErrorHighlight::CoreExt#detailed_message.

  • SyntaxSuggest#detailed_message.

An overriding method must be tolerant of passed keyword arguments, which may include (but may not be limited to):

  • :highlight.

  • :did_you_mean.

  • :error_highlight.

  • :syntax_suggest.

An overrriding method should also be careful with ANSI code enhancements; see Messages.

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));
}
exception(message = nil) → self or new_exception click to toggle source

Returns an exception object of the same class as self; useful for creating a similar exception, but with a different message.

With message nil, returns self:

x0 = StandardError.new('Boom') # => #<StandardError: Boom>
x1 = x0.exception              # => #<StandardError: Boom>
x0.__id__ == x1.__id__         # => true

With string-convertible object message (even the same as the original message), returns a new exception object whose class is the same as self, and whose message is the given message:

x1 = x0.exception('Boom') # => #<StandardError: Boom>
x0..equal?(x1)            # => false
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: true, order: :top) → string click to toggle source

Returns an enhanced message string:

  • Includes the exception class name.

  • If the value of keyword highlight is true (not nil or false), includes bolding ANSI codes (see below) to enhance the appearance of the message.

  • Includes the backtrace:

    • If the value of keyword order is :top (the default), lists the error message and the innermost backtrace entry first.

    • If the value of keyword order is :bottom, lists the error message the the innermost entry last.

Example:

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

Output:

"divided by 0"
["t.rb:3:in `/': divided by 0 (ZeroDivisionError)",
 "\tfrom t.rb:3:in `baz'",
 "\tfrom t.rb:10:in `bar'",
 "\tfrom t.rb:11:in `foo'",
 "\tfrom t.rb:12:in `<main>'"]
["t.rb:3:in `/': \e[1mdivided by 0 (\e[1;4mZeroDivisionError\e[m\e[1m)\e[m",
 "\tfrom t.rb:3:in `baz'",
 "\tfrom t.rb:10:in `bar'",
 "\tfrom t.rb:11:in `foo'",
 "\tfrom t.rb:12:in `<main>'"]

An overrriding method should be careful with ANSI code enhancements; see Messages.

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 click to toggle source

Returns a string representation of self:

x = RuntimeError.new('Boom')
x.inspect # => "#<RuntimeError: Boom>"
x = RuntimeError.new
x.inspect # => "#<RuntimeError: RuntimeError>"
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 click to toggle source

Returns to_s.

See Messages.

static VALUE
exc_message(VALUE exc)
{
    return rb_funcallv(exc, idTo_s, 0, 0);
}
set_backtrace(value) → value click to toggle source

Sets the backtrace value for self; returns the given +value:

x = RuntimeError.new('Boom')
x.set_backtrace(%w[foo bar baz]) # => ["foo", "bar", "baz"]
x.backtrace                      # => ["foo", "bar", "baz"]

The given value must be an array of strings, a single string, or nil.

Does not affect the value returned by backtrace_locations.

See Backtraces.

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));
    }
}
to_s → string click to toggle source

Returns a string representation of self:

x = RuntimeError.new('Boom')
x.to_s # => "Boom"
x = RuntimeError.new
x.to_s # => "RuntimeError"
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);
}