=begin pod

=TITLE class Failure

=SUBTITLE Delayed exception

    class Failure { }

A C<Failure> is a I<soft> or I<unthrown> exception, usually generated by
calling C<&fail>. It acts as a wrapper around an L<Exception> object.

Sink (void) context causes a Failure to throw, i.e. turn into a normal
exception.

Checking a Failure for truth (with the C<Bool> method) or definedness (with
the C<defined> method) marks the failure as handled, and causes it not to
throw in sink context anymore.

You can call the C<handled> method to check if a failure has been handled.

Calling methods on unhandled failures propagates the failure. The
specification says the result is another C<Failure>, in Rakudo it causes the
failure to throw.

=head1 Methods

=head2 method handled

Defined as:

    method handled(Failure:D: --> Bool:D)

Returns C<True> for handled failures, C<False> otherwise.

    sub f() { fail }; my $v = f; say $v.handled; # OUTPUT: «False␤»

=head2 method exception

Defined as:

    method exception(Failure:D: --> Exception)

Returns the L<Exception> object that the failure wraps.

    sub failer() { fail };
    my $failure = failer;
    my $ex = $failure.exception;
    put "$ex.^name(): $ex";
    # OUTPUT: «X::AdHoc: Failed␤»

=head2 method Bool

Defined as:

    multi method Bool(Failure:D: --> Bool:D)

Returns C<False>, and marks the failure as handled.

    sub f() { fail }; my $v = f; say $v.handled; $v.Bool; say $v.handled;
    # OUTPUT: «False␤
    # True␤»

=head2 method defined

Defined as:

    multi method defined(Failure:D: --> Bool:D)

Returns C<False> (failures are officially undefined), and marks
the failure as handled.

    sub f() { fail }; my $v = f; say $v.defined; # OUTPUT: «False␤»

=end pod
