Skip to content
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 28 additions & 14 deletions doc/Language/exceptions.pod6
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ problem.

=head1 Catching exceptions

It's possible to handle exceptional circumstances by supplying a C<CATCH> block:
It's possible to handle exceptional circumstances by supplying a
C<CATCH> block:

die X::IO::DoesNotExist.new(:path("foo/bar"), :trying("zombie copy"));

Expand All @@ -57,18 +58,22 @@ It's possible to handle exceptional circumstances by supplying a C<CATCH> block:

# OUTPUT: «some kind of IO exception was caught!»

Here, we are saying that if any exception of type C<X::IO> occurs, then the
message C<some kind of IO exception was caught!> will be sent to I<stderr>,
which is what C<$*ERR.say> does, getting displayed on whatever constitutes the
standard error device in that moment, which will probably be the console by
default.
Here, we are saying that if any exception of type C<X::IO> occurs, then
the message C<some kind of IO exception was caught!> will be sent to
I<stderr>, which is what C<$*ERR.say> does, getting displayed on
whatever constitutes the standard error device in that moment, which
will probably be the console by default.

A X<C<CATCH>|CATCH> block uses smartmatching similar to how C<given/when>
smartmatches on options, thus it's possible to catch and handle various
categories of exceptions inside a C<when> block.
Note that the match target is a role. To allow user defined exceptions
to match in the same manner, they must implement the given role. Just
existing in the same namespace will look alike but won't match in a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... "make them look alike"?

Copy link
Collaborator Author

@Kaiepi Kaiepi Apr 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a strange paragraph... I think what it's trying to say that other exception types won't match simply because they're in the X namespace, but I don't think explaining how roles can be used with exceptions really fits on this part of the page.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was saying "will look alike" would be better as "will make them look alike". Not getting into anything else.

C<CATCH> block.

To handle all exceptions, use a C<default> statement. This example prints out
almost the same information as the normal backtrace printer.
A X<C<CATCH>|CATCH> block places any exception thrown in its topic
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The anchor to CATCH will be right here. Are you sure this is the best place? Or wouldn't it better to use CATCH block for indexing?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this belongs more on the phasers page.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then it's better if you move the X thingie

variable (C<$_>), thus it's possible to catch and handle various
categories of exceptions inside a C<when> block. To handle all
exceptions, use a C<default> statement. This example prints out almost
the same information as the normal backtrace printer:

CATCH {
default {
Expand All @@ -81,9 +86,18 @@ almost the same information as the normal backtrace printer.
}
}

Note that the match target is a role. To allow user defined exceptions to match
in the same manner, they must implement the given role. Just existing in the
same namespace will look alike but won't match in a C<CATCH> block.
While this is a very common pattern, it is not strictly necessary to use
C<default> or C<when> in a C<CATCH> block. This is done to prevent the
control flow in one from reaching its end where, unless the exception
has been L<resumed|#Resuming_of_exceptions>, the exception will continue
to be thrown. Allowing this can be used for logging purposes, for
instance:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

up to where? The end of the catch block?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. "the end of the block" might be clearer than "its end" here.


=for code :skip-test<creates a file>
# In the outermost block of a script...
my IO::Handle:D $log = open sprintf('logs/%d-%d.txt', $*INIT-INSTANT, $*PID), :a;
CATCH { $log.printf: "[%d] Died with %s: %s$?NL", now, .^name, .message }
END { $log.close }

=head2 Exception handlers and enclosing blocks

Expand Down