Course of Raku / Objects, I/O, and exceptions / Exceptions / Custom exceptions / Exercises / A negative error
Solution: A negative error
Here is a possible solution to the task.
Code
class Negative is Exception {
has $.n;
method message {
"$.n is negative";
}
}
sub check($n) {
Negative.new(n => $n).throw if $n < 0;
return $n;
}
{
say check(-5);
CATCH {
when Negative {
say .message;
}
}
}
Negative.new(n => -10).throw;🦋 You can find the source code in the file negative-error.raku.
Output
-5 is negative
-10 is negative
in block <unit> at negative-error.raku line 24Comments
Negative is Exceptionmakes the class throwable, and itsmessagemethod uses thenattribute to build the text.checkvalidates its input and throws the custom exception for a negative number. The exception travels out ofcheckto theCATCHin the calling block, wherewhen Negativematches it by type and prints the message. Validating input and signalling bad values with a typed exception is a very common, real use of custom exceptions.The
{ … }around the call is there because aCATCHphaser handles the exceptions thrown in its own enclosing block. The block groups the riskycheck(-5)together with theCATCHthat guards it, so the thrown exception is caught right here, and execution resumes just after the block. Without wrapping them in a block, theCATCHwould guard the whole program instead — and once it caught the exception the program would simply end, with no natural place to carry on.The final
Negative.new(n => -10).throwshows the other side of this. It sits outside the block, so nothing catches it: the exception propagates all the way to the top, and the program dies, printing the message and a backtrace to standard error and exiting with a non-zero status. That is the default fate of any exception you do not catch — and exactly why the first throw needed aCATCHto survive.