Subject: | A:A:Exception::Retval only works as expected with Providers if thrown in get_strref |
I have noted that throwing Apache::AxKit::Exception::Retval exceptions in my Providers often resulted in 500 Internal Server Errors. Recently, I found that it worked in some parts of the Provider, but not in others. So, I just wrote the CrashTest.pm Provider which is attached to examine situation.
Short story:
A Retval thrown in process or init will result in a 500. A Retval thrown in exists appears to be ignored. A Retval thrown in get_strref does the Right Thing. I have not examined the other subs.
The CrashTest.pm should be fairly self-explanatory. You can bind it to e.g.
<Location /test/>
PerlHandler AxKit
AxContentProvider Apache::AxKit::Provider::CrashTest
</Location>
then it has a RESTy interface, http://localhost/test/init/401 will return a 500 on my system, http://localhost/test/strref/401 does the Right Thing.
Even when it returns a 500, it will log the -text message in the error.log. Other than that, it doesn't give a lot to go on, my log from running CrashTest with a debug-level of 10:
[Sat Oct 16 23:03:49 2004] [warn] [client 127.0.0.1] [AxKit] Content Provider Override: Apache::AxKit::Provider::CrashTest
[Sat Oct 16 23:03:49 2004] [warn] [client 127.0.0.1] [AxKit] [CrashTest] Data parsed in init: $VAR1 = bless( {\n 'apache' => bless( do{\\(my $o = 138226348)}, 'Apache' ),\n 'sub' => 'init',\n 'err' => '401'\n }, 'Apache::AxKit::Provider::CrashTest' );\n
[Sat Oct 16 23:03:49 2004] [error] 401 in init
I have found the same result on both my systems, that are pretty different, but they have in common that they run 1.6.2. My main test system has Perl 5.8.4 (Debian Sarge).
A workaround of the problem is of course to throw all retvals in get_strref, but then, it feels sort of natural to throw them in init or process... So that's why I submit it as a normal bug. But of course, it could just be me....
Cheers,
Kjetil
package Apache::AxKit::Provider::CrashTest;
use strict;
use warnings;
use Carp;
use vars qw/@ISA/;
@ISA = ('Apache::AxKit::Provider');
use Apache;
use Apache::AxKit::Exception;
use Apache::AxKit::Provider;
use AxKit;
use Data::Dumper;
sub init {
my $self = shift;
my $r = $self->apache_request();
my @uri = split('/', $r->uri);
$self->{sub} = $uri[2];
$self->{err} = $uri[3];
AxKit::Debug(9, "[CrashTest] Data parsed in init: " . Dumper($self));
if ($self->{sub} eq 'init') {
throw Apache::AxKit::Exception::Retval(
return_code => $self->{err},
-text => $self->{err} . " in init");
}
return $self;
}
sub process {
my $self = shift;
if ($self->{sub} eq 'process') {
throw Apache::AxKit::Exception::Retval(
return_code => $self->{err},
-text => $self->{err} . " in process");
}
return 1;
}
sub exists {
my $self = shift;
if ($self->{sub} eq 'exists') {
throw Apache::AxKit::Exception::Retval(
return_code => $self->{err},
-text => $self->{err} . " in exists");
}
return 1;
}
sub key {
my $self = shift;
return $self->{uri} . "/" . $Apache::AxKit::Plugin::BasicSession::session{credential_0};
}
sub mtime {
my $self=shift;
return time();
}
sub get_fh {
throw Apache::AxKit::Exception::IO(
-text => "No fh for News Provider");
}
sub get_strref {
my $self = shift;
if ($self->{sub} eq 'strref') {
throw Apache::AxKit::Exception::Retval(
return_code => $self->{err},
-text => $self->{err} . " in strref");
}
my $str = "<dahut>daaaahuuuuut</dahut>";
return \$str;
}
1;