Exception: Exception

Inherits:
Object show all
Defined in:
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

Construct a new Exception object, optionally passing in

a message.


995
996
997
998
999
1000
1001
1002
# File 'error.c', line 995

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)


1065
1066
1067
1068
1069
# File 'error.c', line 1065

static VALUE
exc_s_to_tty_p(VALUE self)
{
    return rb_stderr_tty_p() ? Qtrue : Qfalse;
}

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)


1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
# File 'error.c', line 1345

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

#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:



1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
# File 'error.c', line 1211

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:



1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
# File 'error.c', line 1259

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:



1324
1325
1326
1327
1328
# File 'error.c', line 1324

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

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



1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
# File 'error.c', line 1017

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:



1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
# File 'error.c', line 1089

static VALUE
exc_full_message(int argc, VALUE *argv, VALUE exc)
{
    VALUE opt, str, emesg, errat;
    enum {kw_highlight, kw_order, kw_max_};
    static ID kw[kw_max_];
    VALUE args[kw_max_] = {Qnil, Qnil};

    rb_scan_args(argc, argv, "0:", &opt);
    if (!NIL_P(opt)) {
	if (!kw[0]) {
#define INIT_KW(n) kw[kw_##n] = rb_intern_const(#n)
	    INIT_KW(highlight);
	    INIT_KW(order);
#undef INIT_KW
	}
	rb_get_kwargs(opt, kw, 0, kw_max_, args);
	switch (args[kw_highlight]) {
	  default:
	    rb_raise(rb_eArgError, "expected true or false as "
		     "highlight: %+"PRIsVALUE, args[kw_highlight]);
	  case Qundef: args[kw_highlight] = Qnil; break;
	  case Qtrue: case Qfalse: case Qnil: break;
	}
	if (args[kw_order] == Qundef) {
	    args[kw_order] = Qnil;
	}
	else {
	    ID id = rb_check_id(&args[kw_order]);
	    if (id == id_bottom) args[kw_order] = Qtrue;
	    else if (id == id_top) args[kw_order] = Qfalse;
	    else {
		rb_raise(rb_eArgError, "expected :top or :bottom as "
			 "order: %+"PRIsVALUE, args[kw_order]);
	    }
	}
    }
    str = rb_str_new2("");
    errat = rb_get_backtrace(exc);
    emesg = rb_get_message(exc);

    rb_error_write(exc, emesg, errat, str, args[kw_highlight], args[kw_order]);
    return str;
}

#inspectString

Return this exception’s class name and message.

Returns:



1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
# File 'error.c', line 1155

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



1142
1143
1144
1145
1146
# File 'error.c', line 1142

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:



1303
1304
1305
1306
1307
# File 'error.c', line 1303

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:



1038
1039
1040
1041
1042
1043
1044
1045
# File 'error.c', line 1038

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