in reply to Re: Re: dying in the wrong place while using CGI::Carp
in thread dying in the wrong place while using CGI::Carp

As I tear into the internals of CGI::Carp, I find that the die() method calls the realdie() method with un-corrected stack backtrace if the ineval() method evaluates to true, and that will happen if the error occurred within an eval, or if it occurred within a mod_perl script (because mod_perl scripts are evaled, according to CGI::Carp's internal comments). I couldn't quite put together what's going on, but the more I look the more I have to say that you just need to find the problem in your script; you're going to be barking up the wrong tree if you try to find it as a bug in CGI::Carp. It's not there.

Your script is committing an error that isn't manifesting itself until some point within CGI::Carp's error handling. Sorry, Perl isn't giving you a very helpful line number. But the problem really is going to be in your script.

Are you able to post your script so we don't have to throw darts at a target in the dark? If you post it as a followup here, be sure to use readmore tags. :)

By the way, one of the most recent updates to CGI::Carp involves the ineval() method (see the POD for CGI::Carp). Could it be that you've upgraded CGI::Carp and now it's catching something it should have caught before?


Dave

  • Comment on Re: Re: Re: dying in the wrong place while using CGI::Carp

Replies are listed 'Best First'.
Re: Re: Re: Re: dying in the wrong place while using CGI::Carp
by esharris (Monk) on Dec 24, 2003 at 22:02 UTC
    Doesn't your initial explanation imply that we uncovered a bug? die doesn't correct the stack trace properly when called within an eval. If a recent update involves the ineval() method, that would explain why the die method use to work until the admin guy updated the module. Anyway, try this code segment. I left work early today, but I was able to recreate the problem on my machine at home.
    #!/usr/bin/perl use strict; use CGI::Carp qw(fatalsToBrowser warningsToBrowser); eval { die "Ouch"; }; if ($@) { print $@, "\n"; } eval { my_die("Ouch"); }; if ($@) { print $@, "\n"; } sub my_die { my ($arg) = @_; if (CGI::Carp::ineval) { $arg = join("", @_); my($file,$line,$id) = CGI::Carp::id(1); $arg .= " at $file line $line." unless $arg=~/\n$/; if ($arg !~ /\n$/) { $arg .= "\n"; } CGI::Carp::realdie $arg; } if (!ref($arg)) { $arg = join("", @_); my($file,$line,$id) = CGI::Carp::id(1); $arg .= " at $file line $line." unless $arg=~/\n$/; &fatalsToBrowser($arg) if $CGI::Carp::WRAP; if (($arg =~ /\n$/) || !exists($ENV{MOD_PERL})) { my $stamp = CGI::Carp::stamp; $arg=~s/^/$stamp/gm; } if ($arg !~ /\n$/) { $arg .= "\n"; } } realdie $arg; }
      While I think that you have stumbled onto an undesirable behavior in CGI::Carp, the bug causing your script to die in the first place is still.... within your script.

      However, that said, here's an interesting observation:

      With CGI::Carp.....

      use CGI::Carp; eval { die "Ouch!" }; print $@, "\n"; __OUTPUT__ Ouch at C:/Perl/lib/CGI/Carp.pm line 312.

      With Carp.pm.....

      use Carp; eval { die "Ouch" }; print $@, "\n"; __OUTPUT__ Ouch at C:\Perl\scripts\mytest.pl line 6.

      And with CORE::die()....

      <p> eval { CORE::die "Ouch" } print $@, "\n"; __OUTPUT__ Ouch at C:\Perl\scripts\mytest.pl line 5.

      The documentation for CGI::Carp says that in the realm of CGI scripts, you can simply replace "use Carp;" with "use CGI::Carp;". You've discovered that it's not quite that simple... their behavior with respect to reporting a fatal that occurred inside an eval is not uniform.


      Dave