[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