[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