[Catalyst] Confused: how to handle system-level errors with fallback pages

Stuart Watt swatt at infobal.com
Tue Aug 31 16:21:18 GMT 2010


  Okay, I managed to rig up something that appears to work. All this =

goes in the main class. The intent is to call validate_components once, =

and use any error it generates as a value for $c->error() in all future =

requests. Any feedback or comments welcome. It could be a little =

cleaner, but any indication about whether the logic is sound would be =

very welcome.

my $validated =3D 0;
my $validation_error;

sub validate_components {
     my ($c) =3D @_;
     return if ($validated);
     $validated =3D 1;

     # Now do the validation. Code that follows should croak if =

something is wrong.
     ...
}

around dispatch =3D> sub {
     my ($orig, $c) =3D @_;
     my $result;
     my $error;
     my $eval_result;

     if (! $validation_error) {
         $eval_result =3D eval {
             $c->validate_components();
         };
         $error =3D $@;
         if ($eval_result || ! $error) {
             $result =3D $c->$orig(@_);
         }
     }

     if ($validation_error || (! $eval_result && $error)) {
         $c->error($validation_error //=3D $error);
     }
     return $result;
};


Stuart Watt
ARM Product Developer
Information Balance

On 8/31/2010 10:50 AM, Stuart Watt wrote:
> Looks like I was wrong in where the error occurred, although the main =

> issue is unchanged. The problem is in finalize rather than prepare.
>
> On 8/31/2010 10:08 AM, Bill Moseley wrote:
>> Even the top-level handle_request is wrapped in an eval, but it tests =

>> $@ instead of the return value of eval like it should.  Is it =

>> possible something is clearing the $@ var?
>>
>> It's pretty easy to edit Catalyst.pm to check.
>>
> I hadn't seen the eval return value issue, although you're right. The =

> error is reported on the console just fine. The problem is, that is =

> the *only* place it is reported. The eval wrapper causes the finalize =

> to be partially skipped.
>
> Here's the stack trace at point of failure (more or less):
>
> $ =3D =

> ARM::Model::User::get_session_store_delegate(ref(ARM::Model::User), =

> 'fbc69cb40a085cae169b26034f64832d12a9c305') called from file =

> `C:/perl/site/5.10.1/lib/Catalyst/Plugin/Session/Store/Delegate.pm' =

> line 56
> $ =3D =

> Catalyst::Plugin::Session::Store::Delegate::get_session_store_delegate(re=
f(ARM), =

> 'fbc69cb40a085cae169b26034f64832d12a9c305') called from file =

> `C:/perl/site/5.10.1/lib/Catalyst/Plugin/Session/Store/Delegate.pm' =

> line 40
> $ =3D =

> Catalyst::Plugin::Session::Store::Delegate::session_store_delegate(ref(AR=
M)) =

> called from file =

> `C:/perl/site/5.10.1/lib/Catalyst/Plugin/Session/Store/Delegate.pm' =

> line 94
> . =3D =

> Catalyst::Plugin::Session::Store::Delegate::store_session_data(ref(ARM), =

> 'expires:fbc69cb40a085cae169b26034f64832d12a9c305', 1283271921) called =

> from file `C:/perl/site/5.10.1/lib/Catalyst/Plugin/Session.pm' line 148
> . =3D Catalyst::Plugin::Session::_save_session_expires(ref(ARM)) called =

> from file `C:/perl/site/5.10.1/lib/Catalyst/Plugin/Session.pm' line 106
> . =3D Catalyst::Plugin::Session::finalize_headers(ref(ARM)) called from =

> file `C:/perl/site/5.10.1/lib/Catalyst.pm' line 1762
> $ =3D Catalyst::finalize(ref(ARM)) called from file =

> `C:/perl/site/5.10.1/lib/Catalyst/Plugin/Compress/Deflate.pm' line 16
> [other plugins here]
> $ =3D Catalyst::Plugin::Session::PerUser::finalize(ref(ARM)) called from =

> file =

> `C:/perl/site/5.10.1/lib/MSWin32-x86-perlio/Class/MOP/Method/Wrapped.pm' =

> line 48
> ...
> $ =3D ARM::finalize(ref(ARM)) called from file =

> `C:/perl/site/5.10.1/lib/Catalyst.pm' line 1927
>
> So, the issue is: because I use =

> Catalyst::Plugin::Session::Store::Delegate, my model methods are =

> called in the finalize. These methods (based on my DBIC model class) =

> die, and this drops all feedback, as finalize_headers is never =

> completed and finalize_body never called. So I could overcome this by =

> fixing my model to never fail - proxying off the DBIC class in some =

> way to fake session handling on error. (Although I suspect this might =

> be better part of Catalyst::Plugin::Session::Store::Delegate.)
>
> The problem is: finalize_headers is normally called after =

> finalize_error, so even if I detect an error, there seems to be no way =

> to go back and display that error. It seems to me that my model code =

> ought to be able to fail in a reasonable way and get something displayed.
>
> --S
>
> Stuart Watt
> ARM Product Developer
> Information Balance
>
>
>
>> -- =

>> Bill Moseley
>> moseley at hank.org <mailto:moseley at hank.org>
>>
>> -- =

>> This message was scanned by ESVA and is believed to be clean.
>> Click here to report this message as spam. =

>> <http://antispam.infobal.com/cgi-bin/learn-msg.cgi?id=3DBAC6E2807E.050DF>
>>
>>
>> _______________________________________________
>> 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.u=
k/
>> Dev site:http://dev.catalyst.perl.org/
>
> -- =

> This message was scanned by ESVA and is believed to be clean.
> Click here to report this message as spam. =

> <http://antispam.infobal.com/cgi-bin/learn-msg.cgi?id=3D339762807E.4BF34>
>
>
> _______________________________________________
> 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.u=
k/
> Dev site: http://dev.catalyst.perl.org/
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.scsys.co.uk/pipermail/catalyst/attachments/20100831/c5fe4=
ab5/attachment.htm


More information about the Catalyst mailing list