[Catalyst] Catching Exceptions
Matt S Trout
dbix-class at trout.me.uk
Mon Apr 3 15:38:27 CEST 2006
Mark Blythe wrote:
> Hi,
>
> I'm using Exception::Class, and I'm trying to figure out how to catch
> a non-fatal exception thrown by a controller which was called from
> another controller via $c->forward(). I started out trying the normal
> Exception::Class way:
>
> sub foo1 : Local {
> my ($self, $c) = @_;
>
> eval {
> $c->forward('foo2');
> };
>
> if (my $e = MyApp::Exception::Special->caught()) {
> ... some special recovery code ...
> }
> }
>
> sub foo2 : Private {
> my ($self, $c) = @_;
>
> MyApp::Exception::Special->throw(message => 'death!');
> }
>
> This fails miserably. The catching code is never triggered, as if
> there was no exception, yet I end up at the Catalyst exception page.
> After a lot of digging, I finally figured out that Catalyst is
> intercepting the exception in forward() and *clearing* $@ as well.
> Some experimentation brought me to this solution:
>
> sub foo1 : Local {
> my ($self, $c) = @_;
>
> $c->forward('foo2');
>
> if ($c->error()) {
> # restore $@ so Exception::Class will work
> local ($@) = @{$c->error()};
>
> if (my $e = MyApp::Exception::Special->caught()) {
> ... some special recovery code ...
> }
> }
> }
>
> Is this the best solution? Has anybody else done this a different (better) way?
While I much prefer just handling $c->error in my own code (and calling e.g.
$self->foo2($c) if I want to see thrown exceptions), you might want to have a
look at Catalyst::Plugin::MortalForward which makes forward die on error.
--
Matt S Trout Offering custom development, consultancy and support
Technical Director contracts for Catalyst, DBIx::Class and BAST. Contact
Shadowcat Systems Ltd. mst (at) shadowcatsystems.co.uk for more information
+ Help us build a better perl ORM: http://dbix-class.shadowcatsystems.co.uk/ +
More information about the Catalyst
mailing list