[Catalyst] Chained and exceptions

Bill Moseley moseley at hank.org
Thu May 9 15:31:42 GMT 2013


On Thu, May 9, 2013 at 7:25 AM, Lukas Thiemeier
<spamcatcher at thiemeier.net>wrote:

> On 05/09/2013 03:25 PM, Bill Moseley wrote:
> > I have a feeling I asked this before, but cannot find the post.
> >
> > [info] Exception powered by Catalyst 5.90030
> >
> > What's the reasoning that chained actions continue to run after an
> > earlier exception?
> >
> >
> > sub start : Chained( '/' ) : CaptureArgs(0) {
> >     warn "in start\n";
> > }
> >
> > sub middle : Chained( 'start' ) : CaptureArgs(0) {
> >     warn "in middle\n";
> >     die "died in middle\n";  # or e.g. throw access violation
> > }
> >
> > sub lastpart : Chained( 'middle' ) : Args(0) {
> >     my ( $self, $c ) =3D @_;
> >     $c->res->body( "finished\n" );
> >     warn "in lastpart\n";
> > }
> >
> > $ script/exception_test.pl <http://exception_test.pl>
> /start/middle/lastpart
> > in start
> > in middle
> > *in lastpart*
> > [error] Caught exception in Exception::Controller::Root->middle "died in
> > middle"
> >
>
> Hi Bill,
>
> This is because you don't want Catalyst to die. Imagine you are running
> a fastcgi server and you accidentally created an action which dies on
> certain user input.
>

Hi Lukas,

Sorry, you missed the point.  Yes, Catalyst traps exceptions.  That is
expected and is done in handle_request when calling $c->dispatch.

I'm talking about breaking a chain of actions.     Why would a later part
of the chain run if an earlier part threw an exception.   For example, what
if an earlier part of a chain threw a access violation.  In that case you
would not want the later chain to run.





> If Catalyst would die, the fastcgi server would die and your whole
> application would not be available anymore. Instead, you want to report
> the incident and keep the fastcgi server (Catalyst) running.
>
> Because of this, every action is wrapped in an "eval{...}". Potential
> errors are logged, but the server keeps running.
>
> See "execute" in Catalyst.pm for implementation details.
>
>
> To solve your problem, you can wrap your unsafe code in an eval or use
> Try::Tiny (or whatever you prefer) and detach if the unsafe code dies.
>
> Your Example would look like this:
>
> use Try::Tiny;
>
> sub start : Chained( '/' ) : CaptureArgs(0) {
>     warn "in start\n";
> }
>
> sub middle : Chained( 'start' ) : CaptureArgs(0) {
>     my ($self, $c) =3D @_;
>     warn "in middle\n";
>     try{
>     die "died in middle\n";  # or e.g. throw access violation
>     }
>     catch{ $c->detach };
> }
>

Don't forget your semicolon. :)



>
> sub lastpart : Chained( 'middle' ) : Args(0) {
>     my ( $self, $c ) =3D @_;
>     $c->res->body( "finished\n" );
>     warn "in lastpart\n";
> }
>
> If you do it like this, actions chained to the unsafe action will not
> get executed if the unsafe action dies. In your case, "lastpart" will
> never be executed, because "middle" always dies.
>
> Lukas
>
> _______________________________________________
> List: Catalyst at lists.scsys.co.uk
> Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
> Searchable archive:
> http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
> Dev site: http://dev.catalyst.perl.org/
>



-- =

Bill Moseley
moseley at hank.org
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20130509/12ba7=
e06/attachment.htm


More information about the Catalyst mailing list