Spec-Zone.ru › Ruby 3

класс Exception

Родитель:
Объект

Класс Exception и его подклассы используются для связи между Kernel#raise и rescue операторами в begin ... end блоках.

Объект Exception содержит информацию об исключении:

  • Его тип (класс исключения).

  • Необязательное описательное сообщение.

  • Необязательная информация о стеке вызовов.

Некоторые встроенные подклассы Exception имеют дополнительные методы: например, NameError#name.

Значения по умолчанию

Два оператора Ruby имеют классы исключений по умолчанию:

  • raise: по умолчанию RuntimeError.

  • rescue: по умолчанию StandardError.

Глобальные переменные

Когда исключение было возбуждено, но ещё не обработано (в rescue, ensure, at_exit и END блоках), устанавливаются две глобальные переменные:

  • $! содержит текущее исключение.

  • $@ содержит его стек вызовов.

Пользовательские исключения

Для предоставления дополнительной или альтернативной информации программа может создавать пользовательские классы исключений, которые наследуются от встроенных классов исключений.

Хорошей практикой является создание библиотекой одного «общего» класса исключений (обычно подкласса StandardError или RuntimeError) и наследование от него других классов исключений. Это позволяет пользователю перехватывать общее исключение, тем самым перехватывая все исключения, которые может генерировать библиотека, даже если в будущих версиях библиотеки будут добавлены новые подклассы исключений.

Например:

class MyLibrary
  class Error < ::StandardError
  end

  class WidgetError < Error
  end

  class FrobError < Error
  end

end

Чтобы обработать как MyLibrary::WidgetError, так и MyLibrary::FrobError, пользователь библиотеки может перехватить MyLibrary::Error.

Встроенные классы Exception

Встроенные подклассы Exception:

  • 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

END_OF_DOCUMENT_MARKER

Методы публичного класса

exception([string]) → an_exception or exc

Без аргумента или если аргумент такой же, как и получатель, вернуть получателя. В противном случае создать новый объект исключения того же класса, что и получатель, но с сообщением, равным string.to_str.

json_create(object) Показать исходный код
# 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

Десериализует JSON строку, создавая новый объект Exception с сообщением m и трассировкой стека b сериализованной с помощью to_json

new(msg = nil) → exception Показать исходный код
exception(msg = nil) → exception
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);
}

Создать новый объект Exception, необязательно передавая сообщение.

to_tty? → true or false Показать исходный код
static VALUE
exc_s_to_tty_p(VALUE self)
{
    return rb_stderr_tty_p() ? Qtrue : Qfalse;
}

Возвращает true , если сообщения исключений будут отправлены в tty.

Методы публичного экземпляра

exc == obj → true or false Показать исходный код
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;
}

Равенство — Если obj не является Exception, возвращает false. В противном случае возвращает true , если exc и obj имеют одинаковый класс, сообщения и трассировку стека.

as_json(*) Показать исходный код
# File ext/json/lib/json/add/exception.rb, line 18
def as_json(*)
  {
    JSON.create_id => self.class.name,
    'm'            => message,
    'b'            => backtrace,
  }
end

Возвращает хеш, который будет преобразован в объект JSON и представит этот объект.

backtrace → array or nil Показать исходный код
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;
}

Возвращает трассировку стека, связанную с исключением. Трассировка — массив строк, каждая из которых содержит либо «имя_файла:номер_строки: в `метод''' либо «имя_файла:номер_строки.''

def a
  raise "boom"
end

def b
  a()
end

begin
  b()
rescue => detail
  print detail.backtrace.join("\n")
end

возвращает:

prog.rb:2:in `a'
prog.rb:6:in `b'
prog.rb:10

В случае, если трассировка стека не задана, возвращается nil.

ex = StandardError.new
ex.backtrace
#=> nil
backtrace_locations → array or nil Показать исходный код
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;
}

Возвращает трассировку стека, связанную с исключением. Этот метод похож на Exception#backtrace, но трассировка — массив объектов Thread::Backtrace::Location.

Этот метод не зависит от Exception#set_backtrace().

cause → an_exception or nil Показать исходный код
static VALUE
exc_cause(VALUE exc)
{
    return rb_attr_get(exc, id_cause);
}

Возвращает предыдущее исключение ($!) в момент поднятия этого исключения. Это полезно для обертывания исключений и сохранения информации об оригинальном исключении.

exception([string]) → an_exception or exc Показать исходный код
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;
}

Без аргумента или если аргумент такой же, как и получатель, вернуть получателя. В противном случае создать новый объект исключения того же класса, что и получатель, но с сообщением, равным string.to_str.

full_message(highlight: bool, order: [:top or :bottom]) → string Показать исходный код
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;
}

Возвращает отформатированную строку исключения. Возвращаемая строка отформатирована так же, как Ruby форматирует неперехваченные исключения в stderr.

Если highlight равен true, обработчик ошибок по умолчанию отправит сообщения в tty.

order должен быть либо :top, либо :bottom, и располагает сообщение об ошибке и внутреннюю трассировку стека вверху или внизу.

Значения этих параметров по умолчанию зависят от $stderr и его tty? в момент вызова.

inspect → string Показать исходный код
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;
}

Возвращает имя класса и сообщение об этом исключении.

message → string Показать исходный код
static VALUE
exc_message(VALUE exc)
{
    return rb_funcallv(exc, idTo_s, 0, 0);
}

Возвращает результат вызова exception.to_s. Обычно это сообщение или имя исключения.

set_backtrace(backtrace) → array Показать исходный код
static VALUE
exc_set_backtrace(VALUE exc, VALUE bt)
{
    return rb_ivar_set(exc, id_bt, rb_check_backtrace(bt));
}

Устанавливает информацию о трассировке стека, связанную с exc. Трассировка должна быть массивом объектов String или одной строкой String в формате, описанном в Exception#backtrace.

to_json(*args) Показать исходный код
# File ext/json/lib/json/add/exception.rb, line 28
def to_json(*args)
  as_json.to_json(*args)
end

Сохраняет имя класса (Exception) с сообщением m и массивом трассировки стека b в виде строки JSON.

to_s → string Показать исходный код
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);
}

Возвращает сообщение об исключении (или имя исключения, если сообщение не задано).

Ruby Core © 1993–2020 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API