[DOC] Doc for exceptions (#11008)
This commit is contained in:
parent
403413e1f1
commit
43d7db3828
@ -84,15 +84,15 @@ A rescue clause:
|
|||||||
- Ends with the first following `rescue`,
|
- Ends with the first following `rescue`,
|
||||||
`else`, `ensure`, or `end` statement.
|
`else`, `ensure`, or `end` statement.
|
||||||
|
|
||||||
|
##### Rescued Exceptions
|
||||||
|
|
||||||
A `rescue` statement may include one or more classes
|
A `rescue` statement may include one or more classes
|
||||||
that are to be rescued;
|
that are to be rescued;
|
||||||
if none is given, StandardError is assumed.
|
if none is given, StandardError is assumed.
|
||||||
|
|
||||||
The rescue clause rescues both the specified class
|
The rescue clause rescues both the specified class
|
||||||
(or StandardError if none given) or any of its subclasses;
|
(or StandardError if none given) or any of its subclasses;
|
||||||
(see [Built-In Exception Classes](rdoc-ref:Exception@Built-In+Exception+Classes)
|
see [Built-In Exception Class Hierarchy](rdoc-ref:Exception@Built-In+Exception+Class+Hierarchy).
|
||||||
for the hierarchy of Ruby built-in exception classes):
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
begin
|
begin
|
||||||
@ -133,6 +133,8 @@ rescue FloatDomainError, ZeroDivisionError
|
|||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
##### Multiple Rescue Clauses
|
||||||
|
|
||||||
An exception handler may contain multiple rescue clauses;
|
An exception handler may contain multiple rescue clauses;
|
||||||
in that case, the first clause that rescues the exception does so,
|
in that case, the first clause that rescues the exception does so,
|
||||||
and those before and after are ignored:
|
and those before and after are ignored:
|
||||||
@ -153,6 +155,8 @@ Output:
|
|||||||
Rescued Errno::ENOENT
|
Rescued Errno::ENOENT
|
||||||
```
|
```
|
||||||
|
|
||||||
|
##### Capturing the Rescued \Exception
|
||||||
|
|
||||||
A `rescue` statement may specify a variable
|
A `rescue` statement may specify a variable
|
||||||
whose value becomes the rescued exception
|
whose value becomes the rescued exception
|
||||||
(an instance of Exception or one of its subclasses:
|
(an instance of Exception or one of its subclasses:
|
||||||
@ -173,10 +177,66 @@ ZeroDivisionError
|
|||||||
divided by 0
|
divided by 0
|
||||||
```
|
```
|
||||||
|
|
||||||
In the rescue clause, these global variables are defined:
|
##### Global Variables
|
||||||
|
|
||||||
- `$!`": the current exception instance.
|
Two read-only global variables always have `nil` value
|
||||||
- `$@`: its backtrace.
|
except in a rescue clause;
|
||||||
|
there:
|
||||||
|
|
||||||
|
- `$!`: contains the rescued exception.
|
||||||
|
- `$@`: contains its backtrace.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```
|
||||||
|
begin
|
||||||
|
1 / 0
|
||||||
|
rescue
|
||||||
|
p $!
|
||||||
|
p $@
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```
|
||||||
|
#<ZeroDivisionError: divided by 0>
|
||||||
|
["t.rb:2:in `/'", "t.rb:2:in `<main>'"]
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Cause
|
||||||
|
|
||||||
|
In a rescue clause, the method Exception#cause returns the previous value of `$!`,
|
||||||
|
which may be `nil`;
|
||||||
|
elsewhere, the method returns `nil`.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```
|
||||||
|
begin
|
||||||
|
raise('Boom 0')
|
||||||
|
rescue => x0
|
||||||
|
puts "Exception: #{x0.inspect}; $!: #{$!.inspect}; cause: #{x0.cause.inspect}."
|
||||||
|
begin
|
||||||
|
raise('Boom 1')
|
||||||
|
rescue => x1
|
||||||
|
puts "Exception: #{x1.inspect}; $!: #{$!.inspect}; cause: #{x1.cause.inspect}."
|
||||||
|
begin
|
||||||
|
raise('Boom 2')
|
||||||
|
rescue => x2
|
||||||
|
puts "Exception: #{x2.inspect}; $!: #{$!.inspect}; cause: #{x2.cause.inspect}."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
|
||||||
|
```
|
||||||
|
Exception: #<RuntimeError: Boom 0>; $!: #<RuntimeError: Boom 0>; cause: nil.
|
||||||
|
Exception: #<RuntimeError: Boom 1>; $!: #<RuntimeError: Boom 1>; cause: #<RuntimeError: Boom 0>.
|
||||||
|
Exception: #<RuntimeError: Boom 2>; $!: #<RuntimeError: Boom 2>; cause: #<RuntimeError: Boom 1>.
|
||||||
|
```
|
||||||
|
|
||||||
#### Else Clause
|
#### Else Clause
|
||||||
|
|
||||||
@ -349,14 +409,120 @@ not just the part after the point of failure.
|
|||||||
|
|
||||||
## Raising an \Exception
|
## Raising an \Exception
|
||||||
|
|
||||||
Raise an exception with method Kernel#raise.
|
\Method Kernel#raise raises an exception.
|
||||||
|
|
||||||
## Custom Exceptions
|
## Custom Exceptions
|
||||||
|
|
||||||
To provide additional or alternate information,
|
To provide additional or alternate information,
|
||||||
you may create custom exception classes;
|
you may create custom exception classes.
|
||||||
each should be a subclass of one of the built-in exception classes:
|
Each should be a subclass of one of the built-in exception classes
|
||||||
|
(commonly StandardError or RuntimeError);
|
||||||
|
see [Built-In Exception Class Hierarchy](rdoc-ref:Exception@Built-In+Exception+Class+Hierarchy).
|
||||||
|
|
||||||
```
|
```
|
||||||
class MyException < StandardError; end
|
class MyException < StandardError; end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Messages
|
||||||
|
|
||||||
|
Every `Exception` object has a message,
|
||||||
|
which is a string that is set at the time the object is created;
|
||||||
|
see Exception.new.
|
||||||
|
|
||||||
|
The message cannot be changed, but you can create a similar object with a different message;
|
||||||
|
see Exception#exception.
|
||||||
|
|
||||||
|
This method returns the message as defined:
|
||||||
|
|
||||||
|
- Exception#message.
|
||||||
|
|
||||||
|
Two other methods return enhanced versions of the message:
|
||||||
|
|
||||||
|
- Exception#detailed_message: adds exception class name, with optional highlighting.
|
||||||
|
- Exception#full_message: adds exception class name and backtrace, with optional highlighting.
|
||||||
|
|
||||||
|
Each of the two methods above accepts keyword argument `highlight`;
|
||||||
|
if the value of keyword `highlight` is `true`,
|
||||||
|
the returned string includes bolding and underlining ANSI codes (see below)
|
||||||
|
to enhance the appearance of the message.
|
||||||
|
|
||||||
|
Any exception class (Ruby or custom) may choose to override either of these methods,
|
||||||
|
and may choose to interpret keyword argument <tt>highlight: true</tt>
|
||||||
|
to mean that the returned message should contain
|
||||||
|
[ANSI codes](https://en.wikipedia.org/wiki/ANSI_escape_code)
|
||||||
|
that specify color, bolding, and underlining.
|
||||||
|
|
||||||
|
Because the enhanced message may be written to a non-terminal device
|
||||||
|
(e.g., into an HTML page),
|
||||||
|
it is best to limit the ANSI codes to these widely-supported codes:
|
||||||
|
|
||||||
|
- Begin font color:
|
||||||
|
|
||||||
|
| Color | ANSI Code |
|
||||||
|
|---------|------------------|
|
||||||
|
| Red | <tt>\\e[31m</tt> |
|
||||||
|
| Green | <tt>\\e[32m</tt> |
|
||||||
|
| Yellow | <tt>\\e[33m</tt> |
|
||||||
|
| Blue | <tt>\\e[34m</tt> |
|
||||||
|
| Magenta | <tt>\\e[35m</tt> |
|
||||||
|
| Cyan | <tt>\\e[36m</tt> |
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
- Begin font attribute:
|
||||||
|
|
||||||
|
| Attribute | ANSI Code |
|
||||||
|
|-----------|-----------------|
|
||||||
|
| Bold | <tt>\\e[1m</tt> |
|
||||||
|
| Underline | <tt>\\e[4m</tt> |
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
- End all of the above:
|
||||||
|
|
||||||
|
| Color | ANSI Code |
|
||||||
|
|-------|-----------------|
|
||||||
|
| Reset | <tt>\\e[0m</tt> |
|
||||||
|
|
||||||
|
It's also best to craft a message that is conveniently human-readable,
|
||||||
|
even if the ANSI codes are included "as-is"
|
||||||
|
(rather than interpreted as font directives).
|
||||||
|
|
||||||
|
## Backtraces
|
||||||
|
|
||||||
|
A _backtrace_ is a record of the methods currently
|
||||||
|
in the [call stack](https://en.wikipedia.org/wiki/Call_stack);
|
||||||
|
each such method has been called, but has not yet returned.
|
||||||
|
|
||||||
|
These methods return backtrace information:
|
||||||
|
|
||||||
|
- Exception#backtrace: returns the backtrace as an array of strings or `nil`.
|
||||||
|
- Exception#backtrace_locations: returns the backtrace as an array
|
||||||
|
of Thread::Backtrace::Location objects or `nil`.
|
||||||
|
Each Thread::Backtrace::Location object gives detailed information about a called method.
|
||||||
|
|
||||||
|
An `Exception` object stores its backtrace value as one of:
|
||||||
|
|
||||||
|
- An array of Thread::Backtrace::Location objects;
|
||||||
|
this is the common case: the exception was raised by the Ruby core or the Ruby standard library.
|
||||||
|
In this case:
|
||||||
|
|
||||||
|
- Exception#backtrace_locations returns the array of Thread::Backtrace::Location objects.
|
||||||
|
- Exception#backtrace returns the array of their string values
|
||||||
|
(`Exception#backtrace_locations.map {|loc| loc.to_s }`).
|
||||||
|
|
||||||
|
- An array of strings;
|
||||||
|
this is an uncommon case: the user manually set the backtrace to an array of strings;
|
||||||
|
In this case:
|
||||||
|
|
||||||
|
- Exception#backtrace returns the array of strings.
|
||||||
|
- Exception#backtrace_locations returns `nil`.
|
||||||
|
|
||||||
|
- `nil`, in which case both methods return `nil`.
|
||||||
|
|
||||||
|
These methods set the backtrace value:
|
||||||
|
|
||||||
|
- Exception#set_backtrace: sets the backtrace value to an array of strings, or to `nil`.
|
||||||
|
- Kernel#raise: sets the backtrace value to an array of Thread::Backtrace::Location objects,
|
||||||
|
or to an array of strings.
|
||||||
|
|
||||||
|
378
error.c
378
error.c
@ -1470,11 +1470,22 @@ exc_init(VALUE exc, VALUE mesg)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* Exception.new(msg = nil) -> exception
|
* Exception.new(message = nil) -> exception
|
||||||
* Exception.exception(msg = nil) -> exception
|
*
|
||||||
|
* Returns a new exception object.
|
||||||
|
*
|
||||||
|
* The given +message+ should be
|
||||||
|
* a {string-convertible object}[rdoc-ref:implicit_conversion.rdoc@String-Convertible+Objects];
|
||||||
|
* 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 # => #<Exception: Exception>
|
||||||
|
* LoadError.new # => #<LoadError: LoadError> # Subclass of Exception.
|
||||||
|
* Exception.new('Boom') # => #<Exception: Boom>
|
||||||
*
|
*
|
||||||
* Construct a new Exception object, optionally passing in
|
|
||||||
* a message.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
@ -1490,12 +1501,24 @@ exc_initialize(int argc, VALUE *argv, VALUE exc)
|
|||||||
* Document-method: exception
|
* Document-method: exception
|
||||||
*
|
*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* exc.exception([string]) -> an_exception or exc
|
* exception(message = nil) -> self or new_exception
|
||||||
*
|
*
|
||||||
* With no argument, or if the argument is the same as the receiver,
|
* Returns an exception object of the same class as +self+;
|
||||||
* return the receiver. Otherwise, create a new
|
* useful for creating a similar exception, but with a different message.
|
||||||
* exception object of the same class as the receiver, but with a
|
*
|
||||||
* message equal to <code>string.to_str</code>.
|
* With +message+ +nil+, returns +self+:
|
||||||
|
*
|
||||||
|
* x0 = StandardError.new('Boom') # => #<StandardError: Boom>
|
||||||
|
* x1 = x0.exception # => #<StandardError: Boom>
|
||||||
|
* x0.__id__ == x1.__id__ # => true
|
||||||
|
*
|
||||||
|
* With {string-convertible object}[rdoc-ref:implicit_conversion.rdoc@String-Convertible+Objects]
|
||||||
|
* +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') # => #<StandardError: Boom>
|
||||||
|
* x0..equal?(x1) # => false
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1514,10 +1537,15 @@ exc_exception(int argc, VALUE *argv, VALUE self)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* exception.to_s -> string
|
* to_s -> string
|
||||||
|
*
|
||||||
|
* Returns a string representation of +self+:
|
||||||
|
*
|
||||||
|
* x = RuntimeError.new('Boom')
|
||||||
|
* x.to_s # => "Boom"
|
||||||
|
* x = RuntimeError.new
|
||||||
|
* x.to_s # => "RuntimeError"
|
||||||
*
|
*
|
||||||
* Returns exception's message (or the name of the exception if
|
|
||||||
* no message is set).
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
@ -1560,7 +1588,7 @@ rb_get_detailed_message(VALUE exc, VALUE opt)
|
|||||||
* call-seq:
|
* call-seq:
|
||||||
* Exception.to_tty? -> true or false
|
* Exception.to_tty? -> true or false
|
||||||
*
|
*
|
||||||
* Returns +true+ if exception messages will be sent to a tty.
|
* Returns +true+ if exception messages will be sent to a terminal device.
|
||||||
*/
|
*/
|
||||||
static VALUE
|
static VALUE
|
||||||
exc_s_to_tty_p(VALUE self)
|
exc_s_to_tty_p(VALUE self)
|
||||||
@ -1620,20 +1648,51 @@ check_order_keyword(VALUE opt)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* exception.full_message(highlight: bool, order: [:top or :bottom]) -> string
|
* full_message(highlight: true, order: :top) -> string
|
||||||
*
|
*
|
||||||
* Returns formatted string of _exception_.
|
* Returns an enhanced message string:
|
||||||
* The returned string is formatted using the same format that Ruby uses
|
|
||||||
* when printing an uncaught exceptions to stderr.
|
|
||||||
*
|
*
|
||||||
* If _highlight_ is +true+ the default error handler will send the
|
* - Includes the exception class name.
|
||||||
* messages to a tty.
|
* - 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}[rdoc-ref:exceptions.md@Backtraces]:
|
||||||
*
|
*
|
||||||
* _order_ must be either of +:top+ or +:bottom+, and places the error
|
* - If the value of keyword +order+ is +:top+ (the default),
|
||||||
* message and the innermost backtrace come at the top or the bottom.
|
* 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.
|
||||||
*
|
*
|
||||||
* The default values of these options depend on <code>$stderr</code>
|
* Example:
|
||||||
* and its +tty?+ at the timing of a call.
|
*
|
||||||
|
* 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 `/': divided by 0 (ZeroDivisionError)",
|
||||||
|
* "\tfrom t.rb:3:in `baz'",
|
||||||
|
* "\tfrom t.rb:10:in `bar'",
|
||||||
|
* "\tfrom t.rb:11:in `foo'",
|
||||||
|
* "\tfrom t.rb:12:in `<main>'"]
|
||||||
|
* ["t.rb:3:in `/': \e[1mdivided by 0 (\e[1;4mZeroDivisionError\e[m\e[1m)\e[m",
|
||||||
|
* "\tfrom t.rb:3:in `baz'",
|
||||||
|
* "\tfrom t.rb:10:in `bar'",
|
||||||
|
* "\tfrom t.rb:11:in `foo'",
|
||||||
|
* "\tfrom t.rb:12:in `<main>'"]
|
||||||
|
*
|
||||||
|
* An overrriding method should be careful with ANSI code enhancements;
|
||||||
|
* see {Messages}[rdoc-ref:exceptions.md@Messages].
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
@ -1662,10 +1721,11 @@ exc_full_message(int argc, VALUE *argv, VALUE exc)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* exception.message -> string
|
* message -> string
|
||||||
*
|
*
|
||||||
* Returns the result of invoking <code>exception.to_s</code>.
|
* Returns #to_s.
|
||||||
* Normally this returns the exception's message or name.
|
*
|
||||||
|
* See {Messages}[rdoc-ref:exceptions.md@Messages].
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
@ -1676,42 +1736,47 @@ exc_message(VALUE exc)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* exception.detailed_message(highlight: bool, **opt) -> string
|
* detailed_message(highlight: false, **kwargs) -> string
|
||||||
*
|
*
|
||||||
* Processes a string returned by #message.
|
* Returns the message string with enhancements:
|
||||||
*
|
*
|
||||||
* It may add the class name of the exception to the end of the first line.
|
* - Includes the exception class name in the first line.
|
||||||
* Also, when +highlight+ keyword is true, it adds ANSI escape sequences to
|
* - If the value of keyword +highlight+ is +true+,
|
||||||
* make the message bold.
|
* includes bolding and underlining ANSI codes (see below)
|
||||||
|
* to enhance the appearance of the message.
|
||||||
*
|
*
|
||||||
* If you override this method, it must be tolerant for unknown keyword
|
* Examples:
|
||||||
* arguments. All keyword arguments passed to #full_message are delegated
|
|
||||||
* to this method.
|
|
||||||
*
|
*
|
||||||
* This method is overridden by did_you_mean and error_highlight to add
|
* begin
|
||||||
* their information.
|
* 1 / 0
|
||||||
|
* rescue => x
|
||||||
|
* p x.message
|
||||||
|
* p x.detailed_message # Class name added.
|
||||||
|
* p x.detailed_message(highlight: true) # Class name, bolding, and underlining added.
|
||||||
|
* end
|
||||||
*
|
*
|
||||||
* A user-defined exception class can also define their own
|
* Output:
|
||||||
* +detailed_message+ method to add supplemental information.
|
|
||||||
* When +highlight+ is true, it can return a string containing escape
|
|
||||||
* sequences, but use widely-supported ones. It is recommended to limit
|
|
||||||
* the following codes:
|
|
||||||
*
|
*
|
||||||
* - Reset (+\e[0m+)
|
* "divided by 0"
|
||||||
* - Bold (+\e[1m+)
|
* "divided by 0 (ZeroDivisionError)"
|
||||||
* - Underline (+\e[4m+)
|
* "\e[1mdivided by 0 (\e[1;4mZeroDivisionError\e[m\e[1m)\e[m"
|
||||||
* - Foreground color except white and black
|
|
||||||
* - Red (+\e[31m+)
|
|
||||||
* - Green (+\e[32m+)
|
|
||||||
* - Yellow (+\e[33m+)
|
|
||||||
* - Blue (+\e[34m+)
|
|
||||||
* - Magenta (+\e[35m+)
|
|
||||||
* - Cyan (+\e[36m+)
|
|
||||||
*
|
*
|
||||||
* Use escape sequences carefully even if +highlight+ is true.
|
* This method is overridden by some gems in the Ruby standard library to add information:
|
||||||
* Do not use escape sequences to express essential information;
|
*
|
||||||
* the message should be readable even if all escape sequences are
|
* - DidYouMean::Correctable#detailed_message.
|
||||||
* ignored.
|
* - ErrorHighlight::CoreExt#detailed_message.
|
||||||
|
* - SyntaxSuggest#detailed_message.
|
||||||
|
*
|
||||||
|
* 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 overrriding method should also be careful with ANSI code enhancements;
|
||||||
|
* see {Messages}[rdoc-ref:exceptions.md@Messages].
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
@ -1730,9 +1795,15 @@ exc_detailed_message(int argc, VALUE *argv, VALUE exc)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* exception.inspect -> string
|
* inspect -> string
|
||||||
|
*
|
||||||
|
* Returns a string representation of +self+:
|
||||||
|
*
|
||||||
|
* x = RuntimeError.new('Boom')
|
||||||
|
* x.inspect # => "#<RuntimeError: Boom>"
|
||||||
|
* x = RuntimeError.new
|
||||||
|
* x.inspect # => "#<RuntimeError: RuntimeError>"
|
||||||
*
|
*
|
||||||
* Return this exception's class name and message.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
@ -1765,38 +1836,31 @@ exc_inspect(VALUE exc)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* exception.backtrace -> array or nil
|
* backtrace -> array or nil
|
||||||
*
|
*
|
||||||
* Returns any backtrace associated with the exception. The backtrace
|
* Returns a backtrace value for +self+;
|
||||||
* is an array of strings, each containing either ``filename:lineNo: in
|
* the returned value depends on the form of the stored backtrace value:
|
||||||
* `method''' or ``filename:lineNo.''
|
|
||||||
*
|
*
|
||||||
* def a
|
* - \Array of Thread::Backtrace::Location objects:
|
||||||
* raise "boom"
|
* returns the array of strings given by
|
||||||
* end
|
* <tt>Exception#backtrace_locations.map {|loc| loc.to_s }</tt>.
|
||||||
|
* This is the normal case, where the backtrace value was stored by Kernel#raise.
|
||||||
|
* - \Array of strings: returns that array.
|
||||||
|
* This is the unusual case, where the backtrace value was explicitly
|
||||||
|
* stored as an array of strings.
|
||||||
|
* - +nil+: returns +nil+.
|
||||||
*
|
*
|
||||||
* def b
|
* Example:
|
||||||
* a()
|
|
||||||
* end
|
|
||||||
*
|
*
|
||||||
* begin
|
* begin
|
||||||
* b()
|
* 1 / 0
|
||||||
* rescue => detail
|
* rescue => x
|
||||||
* print detail.backtrace.join("\n")
|
* x.backtrace.take(2)
|
||||||
* end
|
* end
|
||||||
|
* # => ["(irb):132:in `/'", "(irb):132:in `<top (required)>'"]
|
||||||
*
|
*
|
||||||
* <em>produces:</em>
|
* see {Backtraces}[rdoc-ref:exceptions.md@Backtraces].
|
||||||
*
|
*/
|
||||||
* prog.rb:2:in `a'
|
|
||||||
* prog.rb:6:in `b'
|
|
||||||
* prog.rb:10
|
|
||||||
*
|
|
||||||
* In the case no backtrace has been set, +nil+ is returned
|
|
||||||
*
|
|
||||||
* ex = StandardError.new
|
|
||||||
* ex.backtrace
|
|
||||||
* #=> nil
|
|
||||||
*/
|
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
exc_backtrace(VALUE exc)
|
exc_backtrace(VALUE exc)
|
||||||
@ -1838,13 +1902,24 @@ rb_get_backtrace(VALUE exc)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* exception.backtrace_locations -> array or nil
|
* backtrace_locations -> array or nil
|
||||||
*
|
*
|
||||||
* Returns any backtrace associated with the exception. This method is
|
* Returns a backtrace value for +self+;
|
||||||
* similar to Exception#backtrace, but the backtrace is an array of
|
* the returned value depends on the form of the stored backtrace value:
|
||||||
* Thread::Backtrace::Location.
|
|
||||||
*
|
*
|
||||||
* This method is not affected by Exception#set_backtrace().
|
* - \Array of Thread::Backtrace::Location objects: returns that array.
|
||||||
|
* - \Array of strings or +nil+: returns +nil+.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* begin
|
||||||
|
* 1 / 0
|
||||||
|
* rescue => x
|
||||||
|
* x.backtrace_locations.take(2)
|
||||||
|
* end
|
||||||
|
* # => ["(irb):150:in `/'", "(irb):150:in `<top (required)>'"]
|
||||||
|
*
|
||||||
|
* See {Backtraces}[rdoc-ref:exceptions.md@Backtraces].
|
||||||
*/
|
*/
|
||||||
static VALUE
|
static VALUE
|
||||||
exc_backtrace_locations(VALUE exc)
|
exc_backtrace_locations(VALUE exc)
|
||||||
@ -1882,12 +1957,19 @@ rb_check_backtrace(VALUE bt)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* exc.set_backtrace(backtrace) -> array
|
* set_backtrace(value) -> value
|
||||||
*
|
*
|
||||||
* Sets the backtrace information associated with +exc+. The +backtrace+ must
|
* Sets the backtrace value for +self+; returns the given +value:
|
||||||
* be an array of Thread::Backtrace::Location objects or an array of String objects
|
|
||||||
* or a single String in the format described in Exception#backtrace.
|
|
||||||
*
|
*
|
||||||
|
* x = RuntimeError.new('Boom')
|
||||||
|
* x.set_backtrace(%w[foo bar baz]) # => ["foo", "bar", "baz"]
|
||||||
|
* x.backtrace # => ["foo", "bar", "baz"]
|
||||||
|
*
|
||||||
|
* The given +value+ must be an array of strings, a single string, or +nil+.
|
||||||
|
*
|
||||||
|
* Does not affect the value returned by #backtrace_locations.
|
||||||
|
*
|
||||||
|
* See {Backtraces}[rdoc-ref:exceptions.md@Backtraces].
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
@ -1912,11 +1994,34 @@ rb_exc_set_backtrace(VALUE exc, VALUE bt)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* exception.cause -> an_exception or nil
|
* cause -> exception or nil
|
||||||
|
*
|
||||||
|
* Returns the previous value of global variable <tt>$!</tt>,
|
||||||
|
* which may be +nil+
|
||||||
|
* (see {Global Variables}[rdoc-ref:exceptions.md@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.
|
||||||
*
|
*
|
||||||
* 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
|
static VALUE
|
||||||
@ -1933,11 +2038,11 @@ try_convert_to_exception(VALUE obj)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* exc == obj -> true or false
|
* self == object -> true or false
|
||||||
|
*
|
||||||
|
* Returns whether +object+ is the same class as +self+
|
||||||
|
* and its #message and #backtrace are equal to those of +self+.
|
||||||
*
|
*
|
||||||
* Equality---If <i>obj</i> is not an Exception, returns
|
|
||||||
* <code>false</code>. Otherwise, returns <code>true</code> if <i>exc</i> and
|
|
||||||
* <i>obj</i> share same class, messages, and backtrace.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
@ -3248,66 +3353,30 @@ syserr_eqq(VALUE self, VALUE exc)
|
|||||||
/*
|
/*
|
||||||
* Document-class: Exception
|
* Document-class: Exception
|
||||||
*
|
*
|
||||||
* \Class Exception and its subclasses are used to communicate between
|
* \Class +Exception+ and its subclasses are used to indicate that an error
|
||||||
* Kernel#raise and +rescue+ statements in <code>begin ... end</code> blocks.
|
* or other problem has occurred,
|
||||||
|
* and may need to be handled.
|
||||||
|
* See {Exceptions}[rdoc-ref:exceptions.md].
|
||||||
*
|
*
|
||||||
* An Exception object carries information about an exception:
|
* An +Exception+ object carries certain information:
|
||||||
* - Its type (the exception's class).
|
|
||||||
* - An optional descriptive message.
|
|
||||||
* - Optional backtrace information.
|
|
||||||
*
|
*
|
||||||
* Some built-in subclasses of Exception have additional methods: e.g., NameError#name.
|
* - The type (the exception's class),
|
||||||
|
* commonly StandardError, RuntimeError, or a subclass of one or the other;
|
||||||
|
* see {Built-In Exception Class Hierarchy}[rdoc-ref:Exception@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.
|
||||||
*
|
*
|
||||||
* == Defaults
|
* == Built-In \Exception \Class Hierarchy
|
||||||
*
|
*
|
||||||
* Two Ruby statements have default exception classes:
|
* The hierarchy of built-in subclasses of class +Exception+:
|
||||||
* - +raise+: defaults to RuntimeError.
|
|
||||||
* - +rescue+: defaults to StandardError.
|
|
||||||
*
|
|
||||||
* == Global Variables
|
|
||||||
*
|
|
||||||
* When an exception has been raised but not yet handled (in +rescue+,
|
|
||||||
* +ensure+, +at_exit+ and +END+ blocks), two global variables are set:
|
|
||||||
* - <code>$!</code> contains the current exception.
|
|
||||||
* - <code>$@</code> contains its backtrace.
|
|
||||||
*
|
|
||||||
* == Custom Exceptions
|
|
||||||
*
|
|
||||||
* To provide additional or alternate information,
|
|
||||||
* a program may create custom exception classes
|
|
||||||
* that derive from the built-in exception classes.
|
|
||||||
*
|
|
||||||
* A good practice is for a library to create a single "generic" exception class
|
|
||||||
* (typically a subclass of StandardError or RuntimeError)
|
|
||||||
* and have its other exception classes derive from that class.
|
|
||||||
* This allows the user to rescue the generic exception, thus catching all exceptions
|
|
||||||
* the library may raise even if future versions of the library add new
|
|
||||||
* exception subclasses.
|
|
||||||
*
|
|
||||||
* For example:
|
|
||||||
*
|
|
||||||
* class MyLibrary
|
|
||||||
* class Error < ::StandardError
|
|
||||||
* end
|
|
||||||
*
|
|
||||||
* class WidgetError < Error
|
|
||||||
* end
|
|
||||||
*
|
|
||||||
* class FrobError < Error
|
|
||||||
* end
|
|
||||||
*
|
|
||||||
* end
|
|
||||||
*
|
|
||||||
* To handle both MyLibrary::WidgetError and MyLibrary::FrobError the library
|
|
||||||
* user can rescue MyLibrary::Error.
|
|
||||||
*
|
|
||||||
* == Built-In Exception Classes
|
|
||||||
*
|
|
||||||
* The built-in subclasses of Exception are:
|
|
||||||
*
|
*
|
||||||
* * NoMemoryError
|
* * NoMemoryError
|
||||||
* * ScriptError
|
* * ScriptError
|
||||||
* * LoadError
|
* * {LoadError}[https://docs.ruby-lang.org/en/master/LoadError.html]
|
||||||
* * NotImplementedError
|
* * NotImplementedError
|
||||||
* * SyntaxError
|
* * SyntaxError
|
||||||
* * SecurityError
|
* * SecurityError
|
||||||
@ -3333,13 +3402,14 @@ syserr_eqq(VALUE self, VALUE exc)
|
|||||||
* * RuntimeError
|
* * RuntimeError
|
||||||
* * FrozenError
|
* * FrozenError
|
||||||
* * SystemCallError
|
* * SystemCallError
|
||||||
* * Errno::*
|
* * Errno (and its subclasses, representing system errors)
|
||||||
* * ThreadError
|
* * ThreadError
|
||||||
* * TypeError
|
* * TypeError
|
||||||
* * ZeroDivisionError
|
* * ZeroDivisionError
|
||||||
* * SystemExit
|
* * SystemExit
|
||||||
* * SystemStackError
|
* * SystemStackError
|
||||||
* * fatal
|
* * {fatal}[https://docs.ruby-lang.org/en/master/fatal.html]
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
107
eval.c
107
eval.c
@ -746,32 +746,91 @@ rb_f_raise(int argc, VALUE *argv)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
|
* raise(exception, message = exception.to_s, backtrace = nil, cause: $!)
|
||||||
|
* raise(message = nil, cause: $!)
|
||||||
|
*
|
||||||
|
* Raises an exception;
|
||||||
|
* see {Exceptions}[rdoc-ref:exceptions.md].
|
||||||
|
*
|
||||||
|
* Argument +exception+ sets the class of the new exception;
|
||||||
|
* it should be class Exception or one of its subclasses
|
||||||
|
* (most commonly, RuntimeError or StandardError),
|
||||||
|
* or an instance of one of those classes:
|
||||||
|
*
|
||||||
|
* begin
|
||||||
|
* raise(StandardError)
|
||||||
|
* rescue => x
|
||||||
|
* p x.class
|
||||||
|
* end
|
||||||
|
* # => StandardError
|
||||||
|
*
|
||||||
|
* Argument +message+ sets the stored message in the new exception,
|
||||||
|
* which may be retrieved by method Exception#message;
|
||||||
|
* the message must be
|
||||||
|
* a {string-convertible object}[rdoc-ref:implicit_conversion.rdoc@String-Convertible+Objects]
|
||||||
|
* or +nil+:
|
||||||
|
*
|
||||||
|
* begin
|
||||||
|
* raise(StandardError, 'Boom')
|
||||||
|
* rescue => x
|
||||||
|
* p x.message
|
||||||
|
* end
|
||||||
|
* # => "Boom"
|
||||||
|
*
|
||||||
|
* If argument +message+ is not given,
|
||||||
|
* the message is the exception class name.
|
||||||
|
*
|
||||||
|
* See {Messages}[rdoc-ref:exceptions.md@Messages].
|
||||||
|
*
|
||||||
|
* Argument +backtrace+ sets the stored backtrace in the new exception,
|
||||||
|
* which may be retrieved by method Exception#backtrace;
|
||||||
|
* the backtrace must be an array of strings or +nil+:
|
||||||
|
*
|
||||||
|
* begin
|
||||||
|
* raise(StandardError, 'Boom', %w[foo bar baz])
|
||||||
|
* rescue => x
|
||||||
|
* p x.backtrace
|
||||||
|
* end
|
||||||
|
* # => ["foo", "bar", "baz"]
|
||||||
|
*
|
||||||
|
* If argument +backtrace+ is not given,
|
||||||
|
* the backtrace is set according to an array of Thread::Backtrace::Location objects,
|
||||||
|
* as derived from the call stack.
|
||||||
|
*
|
||||||
|
* See {Backtraces}[rdoc-ref:exceptions.md@Backtraces].
|
||||||
|
*
|
||||||
|
* Keyword argument +cause+ sets the stored cause in the new exception,
|
||||||
|
* which may be retrieved by method Exception#cause;
|
||||||
|
* the cause must be an exception object (Exception or one of its subclasses),
|
||||||
|
* or +nil+:
|
||||||
|
*
|
||||||
|
* begin
|
||||||
|
* raise(StandardError, cause: RuntimeError.new)
|
||||||
|
* rescue => x
|
||||||
|
* p x.cause
|
||||||
|
* end
|
||||||
|
* # => #<RuntimeError: RuntimeError>
|
||||||
|
*
|
||||||
|
* If keyword argument +cause+ is not given,
|
||||||
|
* the cause is the value of <tt>$!</tt>.
|
||||||
|
*
|
||||||
|
* See {Cause}[rdoc-ref:exceptions.md@Cause].
|
||||||
|
*
|
||||||
|
* In the alternate calling sequence,
|
||||||
|
* where argument +exception+ _not_ given,
|
||||||
|
* raises a new exception of the class given by <tt>$!</tt>,
|
||||||
|
* or of class RuntimeError if <tt>$!</tt> is +nil+:
|
||||||
|
*
|
||||||
|
* begin
|
||||||
* raise
|
* raise
|
||||||
* raise(string, cause: $!)
|
* rescue => x
|
||||||
* raise(exception [, string [, array]], cause: $!)
|
* p x
|
||||||
* fail
|
* end
|
||||||
* fail(string, cause: $!)
|
* # => RuntimeError
|
||||||
* fail(exception [, string [, array]], cause: $!)
|
|
||||||
*
|
*
|
||||||
* With no arguments, raises the exception in <code>$!</code> or raises
|
* With argument +exception+ not given,
|
||||||
* a RuntimeError if <code>$!</code> is +nil+. With a single +String+
|
* argument +message+ and keyword argument +cause+ may be given,
|
||||||
* argument, raises a +RuntimeError+ with the string as a message. Otherwise,
|
* but argument +backtrace+ may not be given.
|
||||||
* the first parameter should be an +Exception+ class (or another
|
|
||||||
* object that returns an +Exception+ object when sent an +exception+
|
|
||||||
* message). The optional second parameter sets the message associated with
|
|
||||||
* the exception (accessible via Exception#message), and the third parameter
|
|
||||||
* is an array of callback information (accessible via
|
|
||||||
* Exception#backtrace_locations or Exception#backtrace).
|
|
||||||
* The +cause+ of the generated exception (accessible via Exception#cause)
|
|
||||||
* is automatically set to the "current" exception (<code>$!</code>), if any.
|
|
||||||
* An alternative value, either an +Exception+ object or +nil+, can be
|
|
||||||
* specified via the +:cause+ argument.
|
|
||||||
*
|
|
||||||
* Exceptions are caught by the +rescue+ clause of
|
|
||||||
* <code>begin...end</code> blocks.
|
|
||||||
*
|
|
||||||
* raise "Failed to create socket"
|
|
||||||
* raise ArgumentError, "No parameters", caller_locations
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
Loading…
x
Reference in New Issue
Block a user