On Thu, May 9, 2013 at 7:25 AM, Lukas Thiemeier <spamcatc...@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 ) = @_; > > $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) = @_; > 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 ) = @_; > $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@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 mose...@hank.org
_______________________________________________ List: Catalyst@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/