summaryrefslogtreecommitdiff
path: root/error.c
diff options
context:
space:
mode:
authorBurdette Lamar <[email protected]>2024-06-26 12:31:40 -0500
committerGitHub <[email protected]>2024-06-26 13:31:40 -0400
commit43d7db3828bb4d55184d8965c00ba3157b2c834f (patch)
treee20a302fd219be2094f4f81d52888175f9bb92c1 /error.c
parent403413e1f1d88a1af94ad9a288bfd7c28ef7257d (diff)
[DOC] Doc for exceptions (#11008)
Diffstat (limited to 'error.c')
-rw-r--r--error.c390
1 files changed, 230 insertions, 160 deletions
diff --git a/error.c b/error.c
index dc720856c8..07693197b9 100644
--- a/error.c
+++ b/error.c
@@ -1469,12 +1469,23 @@ exc_init(VALUE exc, VALUE mesg)
}
/*
- * call-seq:
- * Exception.new(msg = nil) -> exception
- * Exception.exception(msg = nil) -> exception
+ * call-seq:
+ * Exception.new(message = 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
@@ -1490,12 +1501,24 @@ exc_initialize(int argc, VALUE *argv, VALUE exc)
* Document-method: exception
*
* call-seq:
- * exc.exception([string]) -> an_exception or exc
+ * exception(message = nil) -> self or new_exception
+ *
+ * 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') # => #<StandardError: Boom>
+ * x1 = x0.exception # => #<StandardError: Boom>
+ * x0.__id__ == x1.__id__ # => true
*
- * With no argument, or if the argument is the same as the receiver,
- * return the receiver. Otherwise, create a new
- * exception object of the same class as the receiver, but with a
- * message equal to <code>string.to_str</code>.
+ * 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:
- * 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
@@ -1557,10 +1585,10 @@ rb_get_detailed_message(VALUE exc, VALUE opt)
}
/*
- * call-seq:
- * Exception.to_tty? -> true or false
+ * call-seq:
+ * 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
exc_s_to_tty_p(VALUE self)
@@ -1620,20 +1648,51 @@ check_order_keyword(VALUE opt)
/*
* call-seq:
- * exception.full_message(highlight: bool, order: [:top or :bottom]) -> string
+ * full_message(highlight: true, order: :top) -> string
+ *
+ * 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}[rdoc-ref:exceptions.md@Backtraces]:
+ *
+ * - 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:
*
- * Returns formatted string of _exception_.
- * The returned string is formatted using the same format that Ruby uses
- * when printing an uncaught exceptions to stderr.
+ * 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
*
- * If _highlight_ is +true+ the default error handler will send the
- * messages to a tty.
+ * Output:
*
- * _order_ must be either of +:top+ or +:bottom+, and places the error
- * message and the innermost backtrace come at the top or the bottom.
+ * "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>'"]
*
- * The default values of these options depend on <code>$stderr</code>
- * and its +tty?+ at the timing of a call.
+ * An overrriding method should be careful with ANSI code enhancements;
+ * see {Messages}[rdoc-ref:exceptions.md@Messages].
*/
static VALUE
@@ -1662,10 +1721,11 @@ exc_full_message(int argc, VALUE *argv, VALUE exc)
/*
* call-seq:
- * exception.message -> string
+ * message -> string
+ *
+ * Returns #to_s.
*
- * Returns the result of invoking <code>exception.to_s</code>.
- * Normally this returns the exception's message or name.
+ * See {Messages}[rdoc-ref:exceptions.md@Messages].
*/
static VALUE
@@ -1676,42 +1736,47 @@ exc_message(VALUE exc)
/*
* call-seq:
- * exception.detailed_message(highlight: bool, **opt) -> string
+ * detailed_message(highlight: false, **kwargs) -> string
+ *
+ * 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.
*
- * Processes a string returned by #message.
+ * Examples:
*
- * It may add the class name of the exception to the end of the first line.
- * Also, when +highlight+ keyword is true, it adds ANSI escape sequences to
- * make the message bold.
+ * begin
+ * 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
*
- * If you override this method, it must be tolerant for unknown keyword
- * arguments. All keyword arguments passed to #full_message are delegated
- * to this method.
+ * Output:
*
- * This method is overridden by did_you_mean and error_highlight to add
- * their information.
+ * "divided by 0"
+ * "divided by 0 (ZeroDivisionError)"
+ * "\e[1mdivided by 0 (\e[1;4mZeroDivisionError\e[m\e[1m)\e[m"
*
- * A user-defined exception class can also define their own
- * +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:
+ * This method is overridden by some gems in the Ruby standard library to add information:
*
- * - Reset (+\e[0m+)
- * - Bold (+\e[1m+)
- * - Underline (+\e[4m+)
- * - Foreground color except white and black
- * - Red (+\e[31m+)
- * - Green (+\e[32m+)
- * - Yellow (+\e[33m+)
- * - Blue (+\e[34m+)
- * - Magenta (+\e[35m+)
- * - Cyan (+\e[36m+)
+ * - DidYouMean::Correctable#detailed_message.
+ * - ErrorHighlight::CoreExt#detailed_message.
+ * - SyntaxSuggest#detailed_message.
*
- * Use escape sequences carefully even if +highlight+ is true.
- * Do not use escape sequences to express essential information;
- * the message should be readable even if all escape sequences are
- * ignored.
+ * 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
@@ -1730,9 +1795,15 @@ exc_detailed_message(int argc, VALUE *argv, VALUE exc)
/*
* 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
@@ -1765,38 +1836,31 @@ exc_inspect(VALUE exc)
/*
* call-seq:
- * exception.backtrace -> array or nil
+ * backtrace -> array or nil
*
- * Returns any backtrace associated with the exception. The backtrace
- * is an array of strings, each containing either ``filename:lineNo: in
- * `method''' or ``filename:lineNo.''
+ * Returns a backtrace value for +self+;
+ * the returned value depends on the form of the stored backtrace value:
*
- * def a
- * raise "boom"
- * end
- *
- * def b
- * a()
- * end
+ * - \Array of Thread::Backtrace::Location objects:
+ * returns the array of strings given by
+ * <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+.
*
- * begin
- * b()
- * rescue => detail
- * print detail.backtrace.join("\n")
- * end
- *
- * <em>produces:</em>
- *
- * prog.rb:2:in `a'
- * prog.rb:6:in `b'
- * prog.rb:10
+ * Example:
*
- * In the case no backtrace has been set, +nil+ is returned
+ * begin
+ * 1 / 0
+ * rescue => x
+ * x.backtrace.take(2)
+ * end
+ * # => ["(irb):132:in `/'", "(irb):132:in `<top (required)>'"]
*
- * ex = StandardError.new
- * ex.backtrace
- * #=> nil
-*/
+ * see {Backtraces}[rdoc-ref:exceptions.md@Backtraces].
+ */
static VALUE
exc_backtrace(VALUE exc)
@@ -1838,13 +1902,24 @@ rb_get_backtrace(VALUE exc)
/*
* call-seq:
- * exception.backtrace_locations -> array or nil
+ * backtrace_locations -> array or nil
+ *
+ * Returns a backtrace value for +self+;
+ * the returned value depends on the form of the stored backtrace value:
*
- * Returns any backtrace associated with the exception. This method is
- * similar to Exception#backtrace, but the backtrace is an array of
- * Thread::Backtrace::Location.
+ * - \Array of Thread::Backtrace::Location objects: returns that array.
+ * - \Array of strings or +nil+: returns +nil+.
+ *
+ * Example:
*
- * This method is not affected by Exception#set_backtrace().
+ * 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
exc_backtrace_locations(VALUE exc)
@@ -1882,12 +1957,19 @@ rb_check_backtrace(VALUE bt)
/*
* call-seq:
- * exc.set_backtrace(backtrace) -> array
+ * set_backtrace(value) -> value
+ *
+ * Sets the backtrace value for +self+; returns the given +value:
+ *
+ * x = RuntimeError.new('Boom')
+ * x.set_backtrace(%w[foo bar baz]) # => ["foo", "bar", "baz"]
+ * x.backtrace # => ["foo", "bar", "baz"]
*
- * Sets the backtrace information associated with +exc+. The +backtrace+ must
- * 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.
+ * 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
@@ -1911,12 +1993,35 @@ rb_exc_set_backtrace(VALUE exc, VALUE bt)
}
/*
- * call-seq:
- * exception.cause -> an_exception or nil
+ * call-seq:
+ * 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
@@ -1933,11 +2038,11 @@ try_convert_to_exception(VALUE obj)
/*
* 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
@@ -3248,66 +3353,30 @@ syserr_eqq(VALUE self, VALUE exc)
/*
* Document-class: Exception
*
- * \Class Exception and its subclasses are used to communicate between
- * Kernel#raise and +rescue+ statements in <code>begin ... end</code> blocks.
+ * \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}[rdoc-ref:exceptions.md].
*
- * An Exception object carries information about an exception:
- * - Its type (the exception's class).
- * - An optional descriptive message.
- * - Optional backtrace information.
+ * An +Exception+ object carries certain 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:
- * - +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:
+ * The hierarchy of built-in subclasses of class +Exception+:
*
* * NoMemoryError
* * ScriptError
- * * LoadError
+ * * {LoadError}[https://docs.ruby-lang.org/en/master/LoadError.html]
* * NotImplementedError
* * SyntaxError
* * SecurityError
@@ -3333,13 +3402,14 @@ syserr_eqq(VALUE self, VALUE exc)
* * RuntimeError
* * FrozenError
* * SystemCallError
- * * Errno::*
+ * * Errno (and its subclasses, representing system errors)
* * ThreadError
* * TypeError
* * ZeroDivisionError
* * SystemExit
* * SystemStackError
- * * fatal
+ * * {fatal}[https://docs.ruby-lang.org/en/master/fatal.html]
+ *
*/
static VALUE