Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses

Logging the results of 'die'

by harmony (Initiate)
on Jun 08, 2001 at 23:51 UTC ( #87036=perlquestion: print w/replies, xml ) Need Help??

harmony has asked for the wisdom of the Perl Monks concerning the following question:

I am connecting to a database using the
DBI->connect(...) or die "Can't connect: DBI::errstr\n";
command. I'd like to print the information from the die to a log file instead of to the screen. I tried enclosing the statement in an eval but got the error message:
Issuing rollback() for database handle being DESTROY'd without explicit disconnect() at dbi line 252. Is there a way to do this?

Replies are listed 'Best First'.
Re: Logging the results of 'die'
by Abigail (Deacon) on Jun 09, 2001 at 00:15 UTC
    Yes, provided everything in your program (and its modules) use die instead of printing to STDERR. (Well, even then there are ways, but I won't go into them now).

    What you need to do is use a die handler. Here's a complete program that logs errors to a file:

    #!/opt/perl/bin/perl use warnings 'all'; use strict; { my ($fh, $logfile); INIT { $logfile = "/var/log/whatever/errors"; open $fh => ">> $logfile" or die "Failed to open $logfile: $!\ +n"; $SIG {__DIE__} = sub { print $fh @_; print $fh "\n" unless $_ [-1] =~ /\n\z/; }; } END { $fh and (close $fh or warn "Failed to close $logfile: $!\n"); } } print "Hello, world\n"; die "Meep, meep!"; print "I should be dead....\n"; __END__

    -- Abigail

Re: Logging the results of 'die'
by lestrrat (Deacon) on Jun 08, 2001 at 23:57 UTC

    I personally would opt for the most straight forward way: Create a sub that logs the results to a file, and then call die.

    # excuse the sloppy code... sub log_and_die { my $msg = shift; # suppose $fh is an already defined, opened # file handle. of course, you can open one here # as well... print $fh $msg; die $msg; } DBI->connect( ... ) || log_and_die( $! )
Re: Logging the results of 'die'
by cLive ;-) (Prior) on Jun 09, 2001 at 00:09 UTC
    Or you could manipulate the __DIE__ token manually. Eg,
    local $SIG{__DIE__} = sub { # get error message my $err = $_[0]; # open error log or exit - you can't die here :) open(ERRLOG,'>>/path/to/errlog') || exit(0); # you may want to add information from the caller() # function here and add other info to log print ERRLOG "Error: $err\nplus whatever else you need...\n\n"; close(ERRLOG); exit(0); }
    Or something like that.

    cLive ;-)

Re: Logging the results of 'die'
by wog (Curate) on Jun 09, 2001 at 00:02 UTC
    What may be happening is that your database handle is not being put anywhere out of the eval. (Thus it is being destroyed.)

    As for a way to make all dies go to a logfile, reopening STDERR to somewhere else at the beginning of the script could help you:

    open STDERR, ">errors.log" or warn "failed to reopen STDERR: $!\n";

    (updated because "actual problem" was the wrong phrase where I used it.)

      Most posts in this thread concentrate on how to catch the error message, but I don't think that's the real issue. wog's message touches on it. The eval should put the database handle somewhere so that a cleanup routine can deal with it in case there's an error. You might try something like this:
      eval { my $dbh = DBI->connect(..., {RaiseError=>1}); eval { $dbh->do("update ..."); $dbh->do("update ..."); }; if ($@) { # clean up after an unsuccessful update $dbh->rollback(); $dbh->disconnect(); die($@); # reraise the error } # successful update $dbh->commit(); $dbh->disconnect(); }; if ($@) { log($@); }
Re: Logging the results of 'die'
by BigJoe (Curate) on Jun 09, 2001 at 00:00 UTC
    Check out the CGI::CarpThis will dump the information to your webserver's log (unless you specify to dump it to the browser). Then Apache/IIS will handle the write and your script can die(croak).


    Learn patience, you must.
    Young PerlMonk, craves Not these things.
    Use the source Luke.
Re: Logging the results of 'die'
by Russ (Deacon) on Jun 08, 2001 at 23:59 UTC
    DBI->connect() or print LOG "Error message\n";
    You could also use the contents of $@. After the eval, the die message will be stored in $@.

    Is that what you need?

    Brainbench 'Most Valuable Professional' for Perl

Re: Logging the results of 'die'
by sz (Friar) on Jun 09, 2001 at 00:02 UTC
    I haven't used it with DBI error, but how about:
    BEGIN { use CGI::Carp qw(carpout); open(LOG, ">>/path/to/my/log") or die("Unable to open log: $!\n"); carpout(LOG); }

Re: Logging the results of 'die'
by mikeB (Friar) on Jun 09, 2001 at 00:00 UTC
    Search CPAN for 'log' or 'logging'. Several logging modules there.

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://87036]
Approved by root
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others lurking in the Monastery: (6)
As of 2022-06-29 09:27 GMT
Find Nodes?
    Voting Booth?
    My most frequent journeys are powered by:

    Results (96 votes). Check out past polls.