123456789_123456789_123456789_123456789_123456789_

Exception: Exception

Overview

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

An Exception object carries certain information:

  • The type (the exception’s class), commonly StandardError, RuntimeError, or a subclass of one or the other; see Built-In Class Hierarchy.

  • An optional descriptive message; see methods ::new, #message.

  • Optional backtrace information; see methods #backtrace, #backtrace_locations, #set_backtrace.

  • An optional cause; see method #cause.

Built-In Exception Class Hierarchy

The hierarchy of built-in subclasses of class Exception:

Class Attribute Summary

Class Method Summary

Instance Method Summary

Constructor Details

.new(message = nil) ⇒ Exception

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>
[ GitHub ]

  
# File 'error.c', line 1490

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 Attribute Details

.to_tty?Boolean (readonly)

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

[ GitHub ]

  
# File 'error.c', line 1592

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

Class Method Details

.exception(message = nil) ⇒ self, 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
[ GitHub ]

Instance Method Details

#==(object) ⇒ Boolean

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

[ GitHub ]

  
# File 'error.c', line 2047

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

[ GitHub ]

  
# File 'error.c', line 1864

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

[ GitHub ]

  
# File 'error.c', line 1923

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 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.
[ GitHub ]

  
# File 'error.c', line 2026

static VALUE
exc_cause(VALUE exc)
{
    return rb_attr_get(exc, id_cause);
}

#detailed_message(highlight: false, **kwargs) ⇒ String

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 overriding method should also be careful with ANSI code enhancements; see Messages.

[ GitHub ]

  
# File 'error.c', line 1781

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, 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
[ GitHub ]

  
# File 'error.c', line 1524

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

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 overriding method should be careful with ANSI code enhancements; see Messages.

[ GitHub ]

  
# File 'error.c', line 1697

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

Returns a string representation of self:

x = RuntimeError.new('Boom')
x.inspect # => "#<RuntimeError: Boom>"
x = RuntimeError.new
x.inspect # => "#<RuntimeError: RuntimeError>"
[ GitHub ]

  
# File 'error.c', line 1808

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 #to_s.

See Messages.

[ GitHub ]

  
# File 'error.c', line 1730

static VALUE
exc_message(VALUE exc)
{
    return rb_funcallv(exc, idTo_s, 0, 0);
}

#set_backtrace(value) ⇒ value

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.

[ GitHub ]

  
# File 'error.c', line 1974

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_sString

Returns a string representation of self:

x = RuntimeError.new('Boom')
x.to_s # => "Boom"
x = RuntimeError.new
x.to_s # => "RuntimeError"
[ GitHub ]

  
# File 'error.c', line 1550

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