Whereceptions
I have a sub that takes a file and tries to guard itself against a file that does not exist. Where clauses don’t make good error messages.
sub run-test(IO() $file where .e & .f) { };
run-test('not-there.txt');
# OUTPUT:
# Constraint type check failed in binding to parameter '$file'; expected anonymous constraint to be met but got IO::Path (IO::Path.new("not-th...)
The signature of that sub is quite expressive. Often we don’t have time to read code to hunt down mistakes. That’s why bad error messages are LTA. We can extend any where clause with a die
or fail
to provide a better message.
sub run-test(IO() $file where .e && .f || fail("file $_ not found")) { };
run-test('not-there.txt');
# OUTPUT:
# file not-there.txt not found
We can also throw exceptions of cause. With just one parameter the signature has gotten quite long already. Also, when working with many files we will write the same code over and over again. Since we don’t code in Java we would rather not to.
my &it-is-a-file = -> IO() $_ {
.e && .f || fail (X::IO::FileNotFound.new(:path(.Str)))
}
sub run-test(IO::Path $file where &it-is-a-file) { }
That’s much better. Since exceptions are classes we can reuse code amongst them. Like coloured output and checking for broken symlinks.
class X::Whereception is Exception is export {
has $.stale-symlink is rw;
method is-dangling-symlink {
$.stale-symlink = do with $.path { .IO.l & !.IO.e };
}
}
class X::IO::FileNotFound is X::Whereception is export {
has $.path;
method message {
RED $.is-dangling-symlink ?? „The file ⟨$.path⟩ is a dangling symlink.“ !! „The file ⟨$.path⟩ was not found.“
}
}
I have added a few to Shell::Piping
. Suggestions what else to check for are very welcome.
-
August 10, 2020 at 14:302020.32 Survey, Please – Rakudo Weekly News