After re-reading my last post, I realized that I neglected to mention one special exception: $Catalyst::DETACH.
When you call $c->detach( ... ), underneath it calls $c->forward( ... ) then dies with a special detach message. Unfortunately, all of our exception handling will catch this too. It's pretty easy to clean this up in our end action:
sub end : Private {
my( $self, $c ) = @_;
if( my( $error ) = @{ $c->error } ) {
if( $error->message eq $Catalyst::DETACH ) {
$c->clear_errors;
}
else {
return;
}
}
# continue on as normal...
}
Without that cleanup, you'd get the error screen every time you would call detach().
I've used custom exceptions for ResourceNotFound, InvalidIdentifier and such regularly in applications in the past and it worked quite well. I also experimented with an un-auto like catching mechanism. For example, the chain segment Foo::Bar::load would throw an ResourceNotFound::Bar exception if it can't find a bar with the passed ID. It would then search in Foo::Bar, and then in Foo for exception handling actions that fit the criteria (catching ResourceNotFound::Bar, ResourceNotFound or FlowException).
I haven't yet come up with a final, clean syntax yet, but I imagine something like:
sub notfound: Catch('ResourceNotFound') { ...
}
Re:++ to all this
LTjake on 2007-04-10T17:57:29
Great idea! It seems like we're inching towards a more robust idea of exception handling.
Right now I'm pretty happy encapsulating some logic inside each exception class -- though something more closely tied to the application would likely be better in some instances.