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

It's hard to be sure without seeing any code at all, as well as without seeing the actual error message. It sounds like you've got a lot of code, and you don't know really where the error is, so it's probably not practical to post a snippet until you've isolated where the problem is. But posting the actual error message could be helpful.

Here is my initial theory:

Update: See my update at the bottom of this post. I think it's more on the mark.

Your admin may have removed the definition of the CGI::Carp error handling routine that is assigned via CGI::Carp::set_message();

Here's an example. The following code executes properly if you uncomment the "carp_error" sub's definition. But we are looking for what might cause an error within the Carp module. So leave the error-handling sub commented out...:

use strict; use warnings; use CGI::Pretty; use CGI::Carp qw( fatalsToBrowser ); BEGIN { # sub carp_error { # my $error_message = shift; # my $cq = new CGI; # print $cq->start_html( "Error" ), # $cq->h1("Error"), # $cq->p( "Sorry, the following error has occurred: " ), # $cq->p( $cq->i( $error_message ) ), # $cq->end_html; # } CGI::Carp::set_message( \&carp_error ); } die $!;

If you call CGI::Carp::set_message(), passing it a reference to a nonexistant error-handling subroutine, you won't know there's a problem until the main script dies for some reason. And then, CGI::Carp tries to call that error-handling routine. And when the call fails because there is no routine, guess what?....

Content-type: text/html Undefined subroutine &main::carp_error called at C:/Perl/lib/CGI/Carp. +pm line 45 6.

Yup, the error message hails back to the Carp module.

Start by trying to figure out if there is a call to CGI::Carp::set_message(), and no definition of the error routine.

Update: I looked into the source on CGI::Carp. Line 301 is part of the sub import() definition. So whatever it is that your script is doing, it's causing an error to ripple into the import() method of CGI::Carp. merlyn (in the CB) had a brilliant suggestion (most of his are). ...make sure that you have a semicolon after use CGI::Carp;. Without one, it's possible that Perl is seeing the next line of code (up to the next semicolon) as an export list, causing the error you're seeing deep inside the CGI::Carp module.

use strict; might catch such an error earlier on by noticing a bareword.


Dave

Replies are listed 'Best First'.
Re: Re: dying in the wrong place while using CGI::Carp
by esharris (Monk) on Dec 24, 2003 at 14:08 UTC
    In CGI::Carp, line 301 looks like this: sub realdie { CORE::die (@_); } The updated die calls realdie. With the help of a colleague, we concluded that the program actually dies in the body of this realdie. This is why we see the .../CGI/Carp.pm file name and the 301 line number. If I copy this code to my script and use this subroutine, the problem is duplicated. The script appears to die in the body of new realdie. Do you agree with my diagnosis? Is this a bug in CGI::Carp? How can I fix realdie so I uses the right file and line number?
      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

        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; }