ETOOBUSY 🚀 minimal blogging for the impatient
Ouch!
TL;DR
Ouch is a great module.
I really thought that I already wrote something about Ouch, but apparently I’m not able to find anything. Maybe it was another personality, go figure.
What is this about?
Anyway, Ouch. It’s an opinionated way of throwing exceptions, which I found extremely attractive considering its simplicity and web-esque-enabling way of working.
This is how you throw an exception, typically:
ouch 404, 'Sorry, I miss this resource'
unless exists $store{$requested_item_id};
ouch 500, "Ooops, seems there's an error in my logic!"
unless makes_sense($current_status);
That’s it, a code for the machine and a message for the human.
I said typically because you can also add a third opaque $data
parameter and basically pass whatever can make sense to track at higher
levels, e.g. to produce better logs:
ouch 401, "Sounds like you can't do that", {
request => $req,
user => $authenticated_user,
};
As I said, a code for the machine and a message for the human, plus data for the digger. Nothing prevents you to use different codes (strings, for example, or different numbers), so it can adapt pretty well to your style.
Catching exceptions
Ouch also provides some syntactic sugar when you catch exceptions. First of all, anyway, let’s see what happens when we’re not doing this:
$ perl -MOuch -e 'ouch 500, "Internal Server Error"'
Internal Server Error at -e line 1.
$ perl -e 'die "Internal Server Error"'
Internal Server Error at -e line 1.
So we’re pretty confident that nothing bad happens when we don’t catch the exception. Let’s do this anyway:
$ perl -MOuch -E '
eval {ouch 500, "Internal Server Error"};
if (kiss 500) {$bugs++; say bleep $@}
elsif (kiss 404) {say bleep $@, ($misses++ > 1) ? ", again" : ""}
'
Internal Server Error
It’s basic Perl exception handling machinery, plus a way to figure out which exception was last thrown, and possibly act on it.
What’s with these function names?
I like the metaphor where the exception is treated like a (hopefully)
minor wound. That’s why you say ouch
when something happens, and
receive a kiss for any different of these something or an overall hug
that addresses them all at once. Also, swearing is not good - so you
bleep
your messages (which actually gets rid of the user-confusing
indication of where the error happened in the code).
It’s not the only interface available, altough I can’t see anything wrong with it. Anyway, in JT Smith’s own words:
Some users are sticks in the mud who can’t bring themselves to
ouch
andkiss
. For them, there is the:trytiny
interface.
So yes, you can use more corporate-y names like throw
instead of
ouch
and caught
instead of kiss
.
Try not to be a stick in the mud though.
Safer handling
There are a few issues with using basic eval
for exception handling in
Perl. I will not trace back to the first who pointed out this, and
just provide you a hook to understand more on this: Try::Tiny
’s
BACKGROUND.
Which usually prompts me to use Try::Catch, i.e. Try::Tiny’s drop-in replacement that addresses these concerns without introducing other ones (from my perspective, at least).
Alas, this means that the exception variable gets changed from $@
(or $EVAL_ERROR
for those fond of English) to $_
(i.e. $ARG
or
the topic). Which messes up with Ouch, that uses the traditional
$@
.
Confession time: I defined this as an impedence mismatch, which I admit: even with a typo, it’s jargon from electronics that might not make any sense for people from other backgrounds. Sorry, my bad, both for the jargon and the typo. But you can learn more about Impedance matching!
Anyway, if you’re into using Try::Tiny or Try::Catch, make sure
to pass option :trytiny_var
when use
ing the module, like this:
use Ouch ':trytiny_var';
so that Ouch will do the right thing and work with $_
by default,
saving you some typing.
Did I convince you?
Let me know! If you want to try this out and don’t know where to start, take a look at Installing Perl Modules!