[cgiapp] Problems with exception handling in CAP::Dispatch

Michael Lackhoff lackhoff at zbmed.uni-koeln.de
Tue May 15 10:17:34 EDT 2012


There seems to be something wrong (or at least not very robust) in
CAP::Dispatch::http_error(). It has the following code:

    warn '[Dispatch] ERROR'
      . ($ENV{REQUEST_URI} ? " for request '$ENV{REQUEST_URI}': " : ': ')
      . $e->error . "\n";

I guess $e is expected to be an Exception::Class object with an error
method but when a run mode dies the error seems to be passed as a string
not an object. So it dies again at this line in http_error with the
following log message (line numbers slightly different due to a few
added debug statements):

[Tue May 15 14:32:10 2012] [error] [client 10.1.20.83] Can't locate
object method "error" via package "Error executing run mode 'test': a
test-die at /opt/myapp/CAP/Search.pm line 96.\n at
/usr/local/lib/perl5/site_perl/5.14.2/CGI/Application/Dispatch.pm line
713\n" (perhaps you forgot to load "Error executing run mode 'test': a
test-die at /opt/myapp/CAP/Search.pm line 96.\n at
/usr/local/lib/perl5/site_perl/5.14.2/CGI/Application/Dispatch.pm line
713\n"?) at
/usr/local/lib/perl5/site_perl/5.14.2/CGI/Application/Dispatch.pm line
444.\n

I tried to debug it myself and perhaps provide a patch but got lost
because I cannot see where or how the exception object should be
created. After all http_error is called from a Try::Tiny catch block
that is not supposed to create an Exception::Class object or what am I
missing here? I guess this is the reason why the author included this
block within the catch:
        unless ( ref $e ) {
            local $@ = $e;
            $e = Exception::Class->caught();
        }
but it does not seem to work as expected. The docs say that caught()
without an argument just returns $@, so the whole thing looks very much
like a noop.

So, how do we get a real exception object that can be passed to
http_error as expected?

[some more tests later:]
Perhaps the unless-block above should be something like:
        unless ( ref $e ) {
            $e = Exception::Class::Base->new($e);
        }
This gets rid of the above error (Can't locate object method...) but
then I do not get anything in the apache error log. The "warn" at the
beginning of http_error does not seem to have any effect. In fact no
debug message I try to create with "warn ..." writes anything to the
apache log file. Any idea where these messages might get lost? Is there
perhaps something in CAP(::Dispatch) messing with $SIG{__WARN__}?


-Michael


More information about the cgiapp mailing list