class Exception

The root of the exception classes. raise takes an instance of one (raise ArgumentError, "bad size" makes it), and rescue without a class catches StandardError and its subclasses only: the direct subclasses of Exception are for what a program does not usually handle (SystemStackError, Task::Cancelled).

e = begin
  raise ArgumentError, "bad size"
rescue => x
  x
end
e.message   # => "bad size"
e.inspect   # => "#<ArgumentError: bad size>"

<prelude>:5171

Class methods

def self.new(message: String = …) -> Exception

An exception with message, not yet raised.

<prelude>:5180

Methods

def message -> String

The message given to new (or to raise), "" without one.

<prelude>:5177

def backtrace -> Array[String]

Where the exception was first raised, innermost frame first, as "file.qz:12:in method" lines. Empty for one never raised. Raising it again keeps the first backtrace, as in Ruby.

<prelude>:5187

def full_message -> String

The class name and the message, "ArgumentError: bad size", followed by the backtrace, one " from file.qz:12:in method" line per frame: what the runtime prints for an exception nothing rescued.

<prelude>:5191

def ==(other: Object) -> Bool

Whether other is this exception: the same object, or a copy of it. Raising an exception that is referred to raises a copy (exceptions are immutable), and Task.blocking copies one across threads; a copy is equal to its original, and to its other copies. Two exceptions made apart are not equal, whatever their messages.

<prelude>:5197

def hash -> Int

Consistent with ==: the same for an exception and its copies.

<prelude>:5199

def cause -> Exception?

The exception being handled when this one was raised, or nil, as Ruby's $!: an exception raised while a rescue clause runs (there or in what it calls) gets the one the clause is handling, and one raised while an ensure clause runs for an exception passing through gets that one. An exception raised again keeps the cause it had. Each task has its own: a Task.timeout or Task.blocking block, which runs in a task (or thread) of its own, starts with none. One another task raised that await, Task.scope, Task.timeout or Task.blocking raises again gets, if it has none, the one handled there (as a Ruby thread's exception raised again by its value).

e = begin
  begin
    raise ArgumentError, "inner"
  rescue
    raise "outer"
  end
rescue => x
  x
end
e.cause.inspect   # => "#<ArgumentError: inner>"

<prelude>:5223

def to_s -> String

The message.

<prelude>:5225

def inspect -> String

#<ArgumentError: bad size>.

<prelude>:5227