[Catalyst] Fatal errors in chained actions

Ronald J Kimball rkimball at pangeamedia.com
Thu Apr 7 18:10:47 GMT 2011


I was surprised to discover that when a chained action throws a fatal
error, Catalyst continues executing the remaining actions in the
chain.  Personally, I had assumed that each action in the chain could
depend on the preceeding actions having been executed successfully.

I've looked at the code in Catalyst::ActionChain, Catalyst::Action,
and Catalyst, so I see how this happens, but I'm not sure it's what
should happen.  Is this the desired behavior?


Here's an example:

sub root : Chained('/') PathPart('chain') CaptureArgs(0) {
  my ($self, $c) = @_;

  die "Oops!";

  $c->stash->{'greeting'} = 'Hello';
}

sub node : Chained('root') PathPart('') CaptureArgs(0) {
  my ($self, $c) = @_;

  die "Oops!";

  $c->stash->{'name'} = 'world';
}

sub test : Chained('node') PathPart('') Args(0) {
  my ($self, $c) = @_;

  $c->stash->{'message'} =
    $c->stash->{'greeting'} . ' ' . $c->stash->{'name'} . '!';

  $c->res->body($c->stash->{'message'});
}


Use of uninitialized value in concatenation (.) or string at
lib/ChainTest/Controller/Root.pm line 67.
Use of uninitialized value in concatenation (.) or string at
lib/ChainTest/Controller/Root.pm line 67.
[info] *** Request 1 (1.000/s) [19323] [Thu Apr  7 13:52:19 2011] ***
[debug] "GET" request for "chain" from "127.0.0.1"
[debug] Path is "/test"
[error] Caught exception in ChainTest::Controller::Root->root "Oops!
at lib/ChainTest/Controller/Root.pm line 51."
[error] Caught exception in ChainTest::Controller::Root->node "Oops!
at lib/ChainTest/Controller/Root.pm line 59."
[debug] Response Code: 500; Content-Type: text/html; charset=utf-8;
Content-Length: 7078
[info] Request took 0.028427s (35.178/s)
.------------------------------------------------------------+-----------.
| Action                                                     | Time      |
+------------------------------------------------------------+-----------+
| /root                                                      | 0.000252s |
| /node                                                      | 0.000113s |
| /test                                                      | 0.000216s |
| /end                                                       | 0.000469s |
'------------------------------------------------------------+-----------'


The test() action assumes that $c->stash->{'greeting'} and
$c->stash->{'name'} have been set.  In this example it's fairly
innocuous, but what if test() was doing something like updating a
database based on those supposed values?

Ronald



More information about the Catalyst mailing list