Which is safer & better & cleaner & more recommended to use?
I used:
sub insert_exec {
my ($self, $c, $args) = @_;
my ($params, $table, $model) = $self->_init({context => $c, args => $args});
eval { $model->insert($table, $params);
};
if ($@) { return $c->show_error($@); } ## error
$c->redirect("/index");
}
But for this kind of cases (see the error part), I have been told that using Try::Tiny is better?
My question is: How would you write this and why would you choose that way?
Update
Thanks to an anonymous user I have been able to correct a bug in my answer. The return
in the catch
block wasn't having the desired effect, as it returned only from the catch
subroutine.
If there was no exception, try
returns the value of the try
block, otherwise the value of the catch
block. So this version correctly executes and returns the value of $c->redirect("/index")
if the insert
succeeded, otherwise it calls and returns the value of $c->show_error($_)
.
sub insert_exec {
my ($self, $c, $args) = @_;
my ($params, $table, $model) = $self->_init({context => $c, args => $args});
try {
$model->insert($table, $params);
$c->redirect("/index");
}
catch {
$c->show_error($_);
};
}
Try::Tiny
is pretty much essential as error handling with eval
is very hard indeed to get right in the general case. The module's documentation says this
This module provides bare bones try/catch/finally statements that are designed to minimize common mistakes with eval blocks, and NOTHING else.
The main focus of this module is to provide simple and reliable error handling for those ... who still want to write correct eval blocks without 5 lines of boilerplate each time.
Your code would look like this
use Try::Tiny;
sub insert_exec {
my ($self, $c, $args) = @_;
my ($params, $table, $model) = $self->_init({context => $c, args => $args});
try {
$model->insert($table, $params);
}
catch {
return $c->show_error($_);
};
$c->redirect("/index");
}
which I hope you'll agree is much nicer.
Two points are notable:
try
and catch
are subroutines coded to look like language words. That means a semicolon after the final closing brace is essential.
For the same reason, return
within the try
or catch
blocks will not work as expected, and will simply exit the block, returning to the parent subroutine. See my update above.
Within the catch
block $@
has its original value from before the try
. The value resulting from the error is in $_
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With