放入 $!
变量(或 CATCH
块中的 $_
)的所有异常都继承自 Exception
。当您使用非异常参数调用 die
或 fail
时,它会被包装到 X::AdHoc
对象中,该对象也继承自 Exception
。
用户定义的异常类也应该继承自 Exception
,并至少定义一个 message
方法。
class X::YourApp::SomeError is Exception {
method message() {
"A YourApp-Specific error occurred: out of coffee!";
}
}
method message(Exception:D: --> Str:D)
这是一个存根,必须由子类覆盖,并且应该返回异常消息。
应特别注意,此方法本身不会产生异常。
try die "Something bad happened";
if ($!) {
say $!.message;
}
method backtrace(Exception:D:)
在 Backtrace
对象中返回与异常关联的回溯,如果没有回溯,则返回空字符串。仅对已抛出至少一次的异常有意义。
try die "Something bad happened";
with $! { .backtrace.print ; }
method throw(Exception:D:)
抛出异常。
my $exception = X::AdHoc.new;
try $exception.throw;
if ($!) { };
method resume(Exception:D:)
在 CATCH
块中处理时,从 .throw
离开的位置恢复控制流。
CATCH { default { .resume } }
method rethrow(Exception:D:)
重新抛出已抛出至少一次的异常。这与 throw
不同,因为它保留了原始回溯。
sub f() { die 'Bad' };
sub g() { f; CATCH { default { .rethrow } } };
g;
CATCH { default { say .backtrace.full } };
multi fail(Exception $e)
method fail(Exception:D:)
退出调用 Routine
并返回一个 Failure
对象,该对象包装异常。
class ForbiddenWord is Exception {
has Str $.word;
method message { "This word is forbidden: «$!word»" }
}
sub say-word ( $word ) {
ForbiddenWord.new(:word($word)).fail if $word eq 'foo';
$word.say;
}
my $result = say-word("foo");
say $result.exception;
例程形式以相同的方式工作,采用替代语法:fail ForbiddenWord.new(:word($word))
。
multi method gist(Exception:D:)
返回异常打印机应为此异常生成的内容。默认实现返回消息和回溯,以换行符分隔。
my $e = X::AdHoc.new(payload => "This exception is pretty bad");
try $e.throw;
if ($!) { say $!.gist; };
method Failure(Exception:D: --> Failure:D)
自 Rakudo 编译器的 2022.06 版本起可用。
将 Exception
强制转换为 Failure
对象。
multi die()
multi die(*@message)
multi die(Exception:D $e)
method die(Exception:D:)
抛出致命 Exception
。默认异常处理程序将列表的每个元素打印到 $*ERR
(STDERR)。
如果未带参数调用子例程形式,则检查 $!
变量 的值。如果将其设置为 .DEFINITE
值,则其值将用作要抛出的 Exception
(如果其类型为 Exception
),否则,将其用作 X::AdHoc
异常的有效负载。如果 $!
不是 .DEFINITE
,则将抛出有效负载为字符串 "Died"
的 X::AdHoc
。
die
默认情况下将打印其发生的行号
但是,该默认行为由 Exception
级别控制,因此可以通过使用 CATCH
捕获异常将其更改为我们想要的任何内容。例如,这可用于禁止行号。
CATCH {
default {
.payload.say
}
};
die "Dead"
抛出一个可恢复的警告异常,该异常被视为控制异常,因此对于大多数正常异常处理程序而言是不可见的。最外层的控制处理程序会将警告打印到 $*ERR
。在打印警告后,异常将在抛出处恢复。要覆盖此行为,请在 CONTROL
块中捕获异常。quietly {...}
块与 try {...}
块相反,因为它将禁止任何警告,但会通过致命异常。
要简单地打印到 $*ERR
,请使用 note
。warn
应保留在威胁情况下使用,而此时您不太想抛出异常。