# class Exception

Descendants of class `Exception` are used to communicate between `Kernel#raise` and `rescue` statements in `begin ... end` blocks. `Exception` objects carry information about the exception – its type (the exception's class name), an optional descriptive string, and optional traceback information. `Exception` subclasses may add additional information like `NameError#name`.

Programs may make subclasses of `Exception`, typically of `StandardError` or `RuntimeError`, to provide custom classes and add additional information. See the subclass list below for defaults for `raise` and `rescue`.

When an exception has been raised but not yet handled (in `rescue`, `ensure`, `at_exit` and `END` blocks) the global variable `$!` will contain the current exception and `$@` contains the current exception's backtrace.

It is recommended that a library should have one subclass of `StandardError` or `RuntimeError` and have specific exception types inherit from it. This allows the user to rescue a generic exception type to catch all exceptions the library may raise even if future versions of the library add new exception subclasses.

For example:

    class MyLibrary
      class Error < RuntimeError
      end

      class WidgetError < Error
      end

      class FrobError < Error
      end

    end

To handle both WidgetError and FrobError the library user can rescue MyLibrary::Error.

The built-in subclasses of `Exception` are:

- `NoMemoryError`

- `ScriptError`

  - `LoadError`

  - `NotImplementedError`

  - `SyntaxError`

- `SecurityError`

- `SignalException`

  - `Interrupt`

- `StandardError` – default for `rescue`

  - `ArgumentError`

    - `UncaughtThrowError`

  - `EncodingError`

  - `FiberError`

  - `IOError`

    - `EOFError`

  - `IndexError`

    - `KeyError`

    - `StopIteration`

  - `LocalJumpError`

  - `NameError`

    - `NoMethodError`

  - `RangeError`

    - `FloatDomainError`

  - `RegexpError`

  - `RuntimeError` – default for `raise`

  - `SystemCallError`

    - Errno::*

  - `ThreadError`

  - `TypeError`

  - `ZeroDivisionError`

- `SystemExit`

- `SystemStackError`

- fatal – impossible to rescue

### Public Class Methods

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

json_create(object) click to toggle source

Deserializes `JSON` string by constructing new `Exception` object with message `m` and backtrace `b` serialized with `to_json`

    # File ext/json/lib/json/add/exception.rb, line 10
    def self.json_create(object)
      result = new(object['m'])
      result.set_backtrace object['b']
      result
    end

new(msg = nil) → exception click to toggle source

Construct a new `Exception` object, optionally passing in a message.

    static VALUE
    exc_initialize(int argc, VALUE *argv, VALUE exc)
    {
        VALUE arg;

        rb_scan_args(argc, argv, "01", &arg);
        rb_ivar_set(exc, id_mesg, arg);
        rb_ivar_set(exc, id_bt, Qnil);

        return exc;
    }

### Public Instance Methods

exc == obj → true or false click to toggle source

Equality—If obj is not an `Exception`, returns `false`. Otherwise, returns `true` if exc and obj share same class, messages, and backtrace.

    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 status = 0;

            obj = rb_protect(try_convert_to_exception, obj, &status);
            if (status || 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;
    }

as_json(*) click to toggle source

Returns a hash, that will be turned into a `JSON` object and represent this object.

    # File ext/json/lib/json/add/exception.rb, line 18
    def as_json(*)
      {
        JSON.create_id => self.class.name,
        'm'            => message,
        'b'            => backtrace,
      }
    end

backtrace → array click to toggle source

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

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

Returns any backtrace associated with the exception. This method is similar to `Exception#backtrace`, but the backtrace is an array of `Thread::Backtrace::Location`.

Now, this method is not affected by `Exception#set_backtrace()`.

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

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

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

exception(string) → an_exception or exc click to toggle source

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

    static VALUE
    exc_exception(int argc, VALUE *argv, VALUE self)
    {
        VALUE exc;

        if (argc == 0) return self;
        if (argc == 1 && self == argv[0]) return self;
        exc = rb_obj_clone(self);
        exc_initialize(argc, argv, exc);

        return exc;
    }

inspect → string click to toggle source

Return this exception's class name and message

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

message → string click to toggle source

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

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

set_backtrace(backtrace) → array click to toggle source

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

    static VALUE
    exc_set_backtrace(VALUE exc, VALUE bt)
    {
        return rb_ivar_set(exc, id_bt, rb_check_backtrace(bt));
    }

to_json(*args) click to toggle source

Stores class name (`Exception`) with message `m` and backtrace array `b` as `JSON` string

    # File ext/json/lib/json/add/exception.rb, line 28
    def to_json(*args)
      as_json.to_json(*args)
    end

to_s → string click to toggle source

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

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