Class Exception
and its subclasses are used to indicate that an error or other problem has occurred, and may need to be handled. See Exceptions.
An Exception
object carries certain information:
The type (the exceptionâs class), commonly StandardError
, RuntimeError
, or a subclass of one or the other; see Built-In Exception Class Hierarchy.
An optional descriptive message; see methods ::new
, message
.
Optional backtrace information; see methods backtrace
, backtrace_locations
, set_backtrace
.
An optional cause; see method cause
.
The hierarchy of built-in subclasses of class Exception
:
Errno
(and its subclasses, representing system errors)
Returns an exception object of the same class as self
; useful for creating a similar exception, but with a different message.
With message
nil
, returns self
:
x0 = StandardError.new('Boom') x1 = x0.exception x0.__id__ == x1.__id__
With string-convertible object message
(even the same as the original message), returns a new exception object whose class is the same as self
, and whose message is the given message
:
x1 = x0.exception('Boom') x0..equal?(x1)Source
def self.json_create(object) result = new(object['m']) result.set_backtrace object['b'] result end
See as_json
.
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); }
Returns a new exception object.
The given message
should be a string-convertible object; see method message
; if not given, the message is the class name of the new instance (which may be the name of a subclass):
Examples:
Exception.new LoadError.new Exception.new('Boom')Source
static VALUE exc_s_to_tty_p(VALUE self) { return RBOOL(rb_stderr_tty_p()); }
Returns true
if exception messages will be sent to a terminal device.
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); }
Returns whether object
is the same class as self
and its message
and backtrace
are equal to those of self
.
def as_json(*) { JSON.create_id => self.class.name, 'm' => message, 'b' => backtrace, } end
Methods Exception#as_json
and Exception.json_create
may be used to serialize and deserialize a Exception object; see Marshal
.
Method Exception#as_json
serializes self
, returning a 2-element hash representing self
:
require 'json/add/exception' x = Exception.new('Foo').as_json
Method JSON.create
deserializes such a hash, returning a Exception object:
Exception.json_create(x)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; }
Returns the backtrace (the list of code locations that led to the exception), as an array of strings.
Example (assuming the code is stored in the file named t.rb
):
def division(numerator, denominator) numerator / denominator end begin division(1, 0) rescue => ex p ex.backtrace loc = ex.backtrace.first p loc.class end
The value returned by this method migth be adjusted when raising (see Kernel#raise
), or during intermediate handling by set_backtrace
.
See also backtrace_locations
that provide the same value, as structured objects. (Note though that two values might not be consistent with each other when backtraces are manually adjusted.)
see Backtraces.
Sourcestatic 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; }
Returns the backtrace (the list of code locations that led to the exception), as an array of Thread::Backtrace::Location
instances.
Example (assuming the code is stored in the file named t.rb
):
def division(numerator, denominator) numerator / denominator end begin division(1, 0) rescue => ex p ex.backtrace_locations loc = ex.backtrace_locations.first p loc.class p loc.path p loc.lineno p loc.label end
The value returned by this method might be adjusted when raising (see Kernel#raise
), or during intermediate handling by set_backtrace
.
See also backtrace
that provide the same value as an array of strings. (Note though that two values might not be consistent with each other when backtraces are manually adjusted.)
See Backtraces.
Sourcestatic VALUE exc_cause(VALUE exc) { return rb_attr_get(exc, id_cause); }
Returns the previous value of global variable $!
, which may be nil
(see Global Variables):
begin raise('Boom 0') rescue => x0 puts "Exception: #{x0}; $!: #{$!}; cause: #{x0.cause.inspect}." begin raise('Boom 1') rescue => x1 puts "Exception: #{x1}; $!: #{$!}; cause: #{x1.cause}." begin raise('Boom 2') rescue => x2 puts "Exception: #{x2}; $!: #{$!}; cause: #{x2.cause}." end end end
Output:
Exception: Boom 0; $!: Boom 0; cause: nil. Exception: Boom 1; $!: Boom 1; cause: Boom 0. Exception: Boom 2; $!: Boom 2; cause: Boom 1.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, VALUE emesg, int highlight); return rb_decorate_message(CLASS_OF(exc), rb_get_message(exc), RTEST(highlight)); }
Returns the message string with enhancements:
Includes the exception class name in the first line.
If the value of keyword highlight
is true
, includes bolding and underlining ANSI codes (see below) to enhance the appearance of the message.
Examples:
begin 1 / 0 rescue => x p x.message p x.detailed_message p x.detailed_message(highlight: true) end
Output:
"divided by 0" "divided by 0 (ZeroDivisionError)" "\e[1mdivided by 0 (\e[1;4mZeroDivisionError\e[m\e[1m)\e[m"
This method is overridden by some gems in the Ruby standard library to add information:
An overriding method must be tolerant of passed keyword arguments, which may include (but may not be limited to):
:highlight
.
:did_you_mean
.
:error_highlight
.
:syntax_suggest
.
An overriding method should also be careful with ANSI code enhancements; see Messages.
Sourcestatic 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; }
Returns an exception object of the same class as self
; useful for creating a similar exception, but with a different message.
With message
nil
, returns self
:
x0 = StandardError.new('Boom') x1 = x0.exception x0.__id__ == x1.__id__
With string-convertible object message
(even the same as the original message), returns a new exception object whose class is the same as self
, and whose message is the given message
:
x1 = x0.exception('Boom') x0..equal?(x1)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; }
Returns an enhanced message string:
Includes the exception class name.
If the value of keyword highlight
is true (not nil
or false
), includes bolding ANSI codes (see below) to enhance the appearance of the message.
Includes the backtrace:
If the value of keyword order
is :top
(the default), lists the error message and the innermost backtrace entry first.
If the value of keyword order
is :bottom
, lists the error message the the innermost entry last.
Example:
def baz begin 1 / 0 rescue => x pp x.message pp x.full_message(highlight: false).split("\n") pp x.full_message.split("\n") end end def bar; baz; end def foo; bar; end foo
Output:
"divided by 0" ["t.rb:3:in 'Integer#/': divided by 0 (ZeroDivisionError)", "\tfrom t.rb:3:in 'Object#baz'", "\tfrom t.rb:10:in 'Object#bar'", "\tfrom t.rb:11:in 'Object#foo'", "\tfrom t.rb:12:in '<main>'"] ["t.rb:3:in 'Integer#/': \e[1mdivided by 0 (\e[1;4mZeroDivisionError\e[m\e[1m)\e[m", "\tfrom t.rb:3:in 'Object#baz'", "\tfrom t.rb:10:in 'Object#bar'", "\tfrom t.rb:11:in 'Object#foo'", "\tfrom t.rb:12:in '<main>'"]
An overriding method should be careful with ANSI code enhancements; see Messages.
Sourcestatic 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; }
Returns a string representation of self
:
x = RuntimeError.new('Boom') x.inspect x = RuntimeError.new x.inspectSource
static VALUE exc_message(VALUE exc) { return rb_funcallv(exc, idTo_s, 0, 0); }
Returns to_s
.
See Messages.
Sourcestatic VALUE exc_set_backtrace(VALUE exc, VALUE bt) { VALUE btobj = rb_location_ary_to_backtrace(bt); if (RTEST(btobj)) { rb_ivar_set(exc, id_bt, btobj); rb_ivar_set(exc, id_bt_locations, btobj); return bt; } else { return rb_ivar_set(exc, id_bt, rb_check_backtrace(bt)); } }
Sets the backtrace value for self
; returns the given value
.
The value
might be:
an array of Thread::Backtrace::Location
;
an array of String
instances;
a single String
instance; or
nil
.
Using array of Thread::Backtrace::Location
is the most consistent option: it sets both backtrace
and backtrace_locations
. It should be preferred when possible. The suitable array of locations can be obtained from Kernel#caller_locations
, copied from another error, or just set to the adjusted result of the current errorâs backtrace_locations
:
require 'json' def parse_payload(text) JSON.parse(text) rescue JSON::ParserError => ex ex.set_backtrace(ex.backtrace_locations[2...]) raise end parse_payload('{"wrong: "json"') begin parse_payload('{"wrong: "json"') rescue => ex p ex.backtrace p ex.backtrace_locations end
When the desired stack of locations is not available and should be constructed from scratch, an array of strings or a singular string can be used. In this case, only backtrace
is affected:
def parse_payload(text) JSON.parse(text) rescue JSON::ParserError => ex ex.set_backtrace(["dsl.rb:34", "framework.rb:1"]) p ex.backtrace p ex.backtrace_locations end parse_payload('{"wrong: "json"')
Calling set_backtrace
with nil
clears up backtrace
but doesnât affect backtrace_locations
:
def parse_payload(text) JSON.parse(text) rescue JSON::ParserError => ex ex.set_backtrace(nil) p ex.backtrace p ex.backtrace_locations end parse_payload('{"wrong: "json"')
On reraising of such an exception, both backtrace
and backtrace_locations
is set to the place of reraising:
def parse_payload(text) JSON.parse(text) rescue JSON::ParserError => ex ex.set_backtrace(nil) raise end begin parse_payload('{"wrong: "json"') rescue => ex p ex.backtrace p ex.backtrace_locations end
See Backtraces.
Sourcedef to_json(*args) as_json.to_json(*args) end
Returns a JSON
string representing self
:
require 'json/add/exception' puts Exception.new('Foo').to_json
Output:
{"json_class":"Exception","m":"Foo","b":null}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); }
Returns a string representation of self
:
x = RuntimeError.new('Boom') x.to_s x = RuntimeError.new x.to_s
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.3