класс Exception
Потомки класса Исключение используются для обмена сообщениями между Kernel#raise и rescue операторами в begin ... end блоках. Объекты Исключение содержат информацию об исключении — его тип (имя класса исключения), необязательную описательную строку и необязательную информацию об отслеживании стека. Подклассы Исключение могут добавлять дополнительную информацию, например, NameError#name.
Программы могут создавать подклассы Исключение, как правило, от StandardError или RuntimeError, чтобы предоставить пользовательские классы и добавить дополнительную информацию. См. список подклассов ниже для значений по умолчанию для raise и rescue.
Когда исключение было возбуждено, но ещё не обработано (в rescue, ensure, at_exit и END блоках), глобальная переменная $! будет содержать текущее исключение, а $@ — текущий стек вызовов исключения.
Рекомендуется, чтобы библиотека имела один подкласс StandardError или RuntimeError, а специфические типы исключений наследовали от него. Это позволяет пользователю перехватывать общий тип исключения, чтобы поймать все исключения, которые может генерировать библиотека, даже если в будущих версиях библиотеки будут добавлены новые подклассы исключений.
Например:
class MyLibrary class Error < RuntimeError end class WidgetError < Error end class FrobError < Error end end
Для обработки как WidgetError, так и FrobError пользователь библиотеки может перехватить MyLibrary::Error.
Встроенные подклассы Исключение:
-
StandardError — значение по умолчанию для
rescue-
RuntimeError — значение по умолчанию для
raise -
-
Errno::*
-
-
fatal — невозможно перехватить
Методы публичного класса
Без аргумента или если аргумент такой же, как и получатель, возвращает получатель. В противном случае создаёт новый объект исключения того же класса, что и получатель, но с сообщением, равным string.to_str.
# 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, создавая новый объект Исключение с сообщением m и трассировкой стека вызовов b , сериализованной с помощью to_json
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;
} Создаёт новый объект Исключение, необязательно передавая сообщение.
static VALUE
exc_s_to_tty_p(VALUE self)
{
return rb_stderr_tty_p() ? Qtrue : Qfalse;
} Возвращает true, если сообщения об ошибках будут отправлены в tty.
Методы публичного экземпляра
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 имеют одинаковый класс, сообщения и трассировку стека вызовов.
# 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 и представлять этот объект.
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
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;
} Возвращает любую трассировку стека вызовов, связанную с исключением. Этот метод похож на #backtrace, но трассировка стека вызовов является массивом Thread::Backtrace::Location.
Теперь этот метод не зависит от #set_backtrace.
static VALUE
exc_cause(VALUE exc)
{
return rb_attr_get(exc, id_cause);
} Возвращает предыдущее исключение ($!) в момент возникновения этого исключения. Это полезно для обертывания исключений и сохранения информации об исходном исключении.
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;
} Без аргумента или если аргумент такой же, как и получатель, возвращает получатель. В противном случае создаёт новый объект исключения того же класса, что и получатель, но с сообщением, равным string.to_str.
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 :down 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;
} Возвращает отформатированную строку исключения. Возвращённая строка отформатирована таким же образом, как Руби форматирует неперехваченные исключения в stderr.
Если подсветка равна true, обработчик ошибок по умолчанию отправит сообщения в tty.
Порядок должен быть либо :top, либо :bottom, и помещает сообщение об ошибке и внутреннюю трассировку стека вызовов вверху или внизу.
Значения параметров по умолчанию зависят от $stderr и его tty? в момент вызова.
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;
} Возвращает имя класса и сообщение об этом исключении.
static VALUE
exc_message(VALUE exc)
{
return rb_funcallv(exc, idTo_s, 0, 0);
} Возвращает результат вызова exception.to_s. Обычно возвращает сообщение или имя исключения.
static VALUE
exc_set_backtrace(VALUE exc, VALUE bt)
{
return rb_ivar_set(exc, id_bt, rb_check_backtrace(bt));
} Устанавливает информацию о трассировке стека вызовов, связанную с exc. Трассировка стека вызовов должна быть массивом объектов String или одной строкой в формате, описанном в #backtrace.
# File ext/json/lib/json/add/exception.rb, line 28 def to_json(*args) as_json.to_json(*args) end
Сохраняет имя класса (Исключение) с сообщением m и массивом трассировки стека вызовов b в виде строки JSON.
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–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.