Spec-Zone.ru › Ruby 3.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

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

exception([string]) → an_exception or exc

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

json_create(object) Показать исходный код
# File ext/json/lib/json/add/exception.rb, line 9
def self.json_create(object)
  result = new(object['m'])
  result.set_backtrace object['b']
  result
end

См. as_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 RBOOL(rb_stderr_tty_p());
}

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

Открытые методы экземпляра

exc == obj → true or false Show source
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);
}

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

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

Методы Exception#as_json и Exception.json_create могут использоваться для сериализации и десериализации объекта Exception; см. Marshal.

Метод Exception#as_json сериализует self, возвращая хэш из двух элементов, представляющий self:

require 'json/add/exception'
x = Exception.new('Foo').as_json # => {"json_class"=>"Exception", "m"=>"Foo", "b"=>nil}

Метод JSON.create десериализует такой хэш, возвращая объект Exception:

Exception.json_create(x) # => #<Exception: Foo>
backtrace → array or nil Show source
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 Show source
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 Show source
static VALUE
exc_cause(VALUE exc)
{
    return rb_attr_get(exc, id_cause);
}

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

detailed_message(highlight: bool, **opt) → string Show source
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, const VALUE emesg, int highlight);

    return rb_decorate_message(CLASS_OF(exc), rb_get_message(exc), RTEST(highlight));
}

Обрабатывает строку, возвращаемую message.

Он может добавить имя класса исключения в конец первой строки. Кроме того, когда ключевое слово highlight имеет значение true, оно добавляет последовательности ANSI-побега, чтобы сделать сообщение жирным.

Если вы переопределяете этот метод, он должен быть толерантен к неизвестным аргументам ключевых слов. Все аргументы ключевых слов, переданные в full_message, передаются этому методу.

Этот метод переопределяется did_you_mean и error_highlight для добавления их информации.

Пользовательский класс исключений также может определить свой собственный метод detailed_message для добавления дополнительной информации. Когда highlight равно true, он может возвращать строку, содержащую escape-последовательности, но использовать широко поддерживаемые. Рекомендуется ограничить следующие коды:

  • Сброс (\e[0m)

  • Жирный (\e[1m)

  • Подчеркивание (\e[4m)

  • Цвет переднего плана, кроме белого и черного

    • Красный (\e[31m)

    • Зеленый (\e[32m)

    • Желтый (\e[33m)

    • Синий (\e[34m)

    • Пурпурный (\e[35m)

    • Бирюзовый (\e[36m)

Используйте escape-последовательности осторожно, даже если highlight равно true. Не используйте escape-последовательности для выражения важной информации; сообщение должно быть читаемым, даже если все escape-последовательности игнорируются.

exception([string]) → an_exception or exc Show source
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 Show source
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;
}

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

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

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

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

inspect → string Show source
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 Show source
static VALUE
exc_message(VALUE exc)
{
    return rb_funcallv(exc, idTo_s, 0, 0);
}

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

set_backtrace(backtrace) → array Show source
static VALUE
exc_set_backtrace(VALUE exc, VALUE bt)
{
    return rb_ivar_set(exc, id_bt, rb_check_backtrace(bt));
}

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

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

Возвращает строку JSON, представляющую self:

require 'json/add/exception'
puts Exception.new('Foo').to_json

Вывод:

{"json_class":"Exception","m":"Foo","b":null}
to_s → string Show source
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–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

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