# # 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 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](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. # # ## Built-In Exception Class Hierarchy # # The hierarchy of built-in subclasses of class `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 (and its subclasses, representing system errors) # * ThreadError # * TypeError # * ZeroDivisionError # * SystemExit # * SystemStackError # * [fatal](rdoc-ref:fatal) # class Exception # # Returns `true` if exception messages will be sent to a terminal device. # def self.to_tty?: () -> bool # # 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__ # => 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') # => # # x0..equal?(x1) # => false # def self.exception: (?string | _ToS msg) -> instance # # Returns whether `object` is the same class as `self` and its #message and # #backtrace are equal to those of `self`. # def ==: (untyped obj) -> bool # # 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 # # ["t.rb:2:in 'Integer#/'", "t.rb:2:in 'Object#division'", "t.rb:6:in '
'"] # loc = ex.backtrace.first # p loc.class # # String # 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](rdoc-ref:exceptions.md@Backtraces). # def backtrace: () -> Array[String]? # # 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 # # ["t.rb:2:in 'Integer#/'", "t.rb:2:in 'Object#division'", "t.rb:6:in '
'"] # loc = ex.backtrace_locations.first # p loc.class # # Thread::Backtrace::Location # p loc.path # # "t.rb" # p loc.lineno # # 2 # p loc.label # # "Integer#/" # 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](rdoc-ref:exceptions.md@Backtraces). # def backtrace_locations: () -> Array[Thread::Backtrace::Location]? # # Returns the previous value of global variable `$!`, 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. # def cause: () -> Exception? # # 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 # Class name added. # p x.detailed_message(highlight: true) # Class name, bolding, and underlining added. # 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: # # * DidYouMean::Correctable#detailed_message. # * 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 overriding method should also be careful with ANSI code enhancements; see # [Messages](rdoc-ref:exceptions.md@Messages). # def detailed_message: (?highlight: bool?, **untyped ignored) -> String # # 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__ # => 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') # => # # x0..equal?(x1) # => false # def exception: (?self) -> self | (string | _ToS message) -> instance # # 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 # => # # LoadError.new # => # # Subclass of Exception. # Exception.new('Boom') # => # # def initialize: (?string | _ToS message) -> void # # Returns a string representation of `self`: # # x = RuntimeError.new('Boom') # x.inspect # => "#" # x = RuntimeError.new # x.inspect # => "#" # def inspect: () -> String # # Returns #to_s. # # See [Messages](rdoc-ref:exceptions.md@Messages). # def message: () -> String # # 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) # test.rb, line 4 # rescue JSON::ParserError => ex # ex.set_backtrace(ex.backtrace_locations[2...]) # raise # end # # parse_payload('{"wrong: "json"') # # test.rb:4:in 'Object#parse_payload': unexpected token at '{"wrong: "json"' (JSON::ParserError) # # # # An error points to the body of parse_payload method, # # hiding the parts of the backtrace related to the internals # # of the "json" library # # # The error has both #backtace and #backtrace_locations set # # consistently: # begin # parse_payload('{"wrong: "json"') # rescue => ex # p ex.backtrace # # ["test.rb:4:in 'Object#parse_payload'", "test.rb:20:in '
'"] # p ex.backtrace_locations # # ["test.rb:4:in 'Object#parse_payload'", "test.rb:20:in '
'"] # 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"]) # # The error have the new value in #backtrace: # p ex.backtrace # # ["dsl.rb:34", "framework.rb:1"] # # # but the original one in #backtrace_locations # p ex.backtrace_locations # # [".../json/common.rb:221:in 'JSON::Ext::Parser.parse'", ...] # 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 # # nil # p ex.backtrace_locations # # [".../json/common.rb:221:in 'JSON::Ext::Parser.parse'", ...] # 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 # test.rb, line 7 # end # # begin # parse_payload('{"wrong: "json"') # rescue => ex # p ex.backtrace # # ["test.rb:7:in 'Object#parse_payload'", "test.rb:11:in '
'"] # p ex.backtrace_locations # # ["test.rb:7:in 'Object#parse_payload'", "test.rb:11:in '
'"] # end # # See [Backtraces](rdoc-ref:exceptions.md@Backtraces). # def set_backtrace: (String | Array[String]) -> Array[String] | (Array[Thread::Backtrace::Location]) -> Array[Thread::Backtrace::Location] | (nil) -> nil # # Returns a string representation of `self`: # # x = RuntimeError.new('Boom') # x.to_s # => "Boom" # x = RuntimeError.new # x.to_s # => "RuntimeError" # def to_s: () -> 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: # # 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 '
'"] # ["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 '
'"] # # An overriding method should be careful with ANSI code enhancements; see # [Messages](rdoc-ref:exceptions.md@Messages). # def full_message: (?highlight: bool?, ?order: (:top | :bottom | string)?) -> String end