放入 $! 变量(或 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 应保留在威胁情况下使用,而此时您不太想抛出异常。
Exception 的类型关系
展开上面的图表