Re: die function and notifications
by broquaint (Abbot) on May 22, 2003 at 14:51 UTC
|
I'm wondering if it is possible to have the die() function do some actions before it completely dies.
As long as you're careful you create a $SIG{__DIE__} handler to do what you want e.g
$SIG{__DIE__} = sub { print "and the rest was silence ...\n" };
die();
__output__
and the rest was silence ...
Died at - line 2.
Check out Argument stringification in __WARN__ and __DIE__ and Re: How "safe" is die() in %SIG? for some info on the foibles of using the $SIG{__DIE__} handler.
HTH
_________ broquaint | [reply] [d/l] |
Re: die function and notifications
by jdporter (Paladin) on May 22, 2003 at 14:44 UTC
|
| [reply] [d/l] [select] |
Re: die function and notifications
by physi (Friar) on May 22, 2003 at 15:36 UTC
|
You can also do your clean-up in the END block:
#!/usr/bin/perl
die("Die just another day!\n");
END {print "Still alive to clean up\n"}
-----------------------------------
--the good, the bad and the physi--
-----------------------------------
| [reply] [d/l] |
|
|
This is what I've ended up doing. I test for the return code of a call to an external program and if that returns a non-zero, I die and pass the return code to the END from die. Then, within the END, I test $? to see if it is greater than zero, if it is, then I copy the log with an error message and send an alert. Otherwise I copy the log with a different name and exit completely with a 0. This may be kludgy but it seems to work (for the moment). using eval() and $@ does not work so well because I can't get the error messages into $@ (at least not yet).
&My::custom_routine("TESTTRANSFER");
my $rc=$?>>8;
die ($rc) if ($rc > 0);
END {
if ($? > 0) {
print STDERR "TEST.PL Died with error.\n";
copy("TEST.LOG", "TEST.ERROR");
&My::pager("TEST ERROR MESSAGE.");
}else{
print STDERR "TEST.PL completed successfully.\n";
copy("TEST.LOG", "TEST.GOOD");
exit 0;
}
}
Thanks for the help.
"Ex libris un peut de tout" | [reply] [d/l] |
Re: die function and notifications
by dpuu (Chaplain) on May 22, 2003 at 15:08 UTC
|
I was going to suggest $SIG{__DIE__}, but broquaint got there first. So instead I'll suggest that you wrap your entire progream in an eval block:
eval { ... };
if ($@ ne "")
{
my $error = $@;
cleanup();
die "error was: $error\n";
}
See also: http://www.c2.com/cgi/wiki?ExceptionHandlingInPerl.
--Dave | [reply] [d/l] |
Re: die function and notifications
by jaa (Friar) on May 22, 2003 at 15:19 UTC
|
All interesting suggestions so far - but we found too many issues with setting up DIE signal handlers for us to trust it in production.
What we ended up doing, as we had a LOT of legacy stuff, some not written in Perl, was to write a Perl program we call 'run' and use this to execute ALL our stuff - a wrapper for all our processing.
The RUN program uses the open3() function to run the process as a child, and captures all STDOUT and STDERR as well as hooking its own STDIN into the child.
Yes - *NIX specific - havent had to do any large processing on NT
RUN checks exit status, signal and core flags of the child process, and sends us an email if the exit is non-zero
RUN is great for enforcing a standardised environment on the child processes - we never have issues running stuff on production because something in the environment or path is missing, not-found etc etc
RUN is also great for preventing cron output from generating unexpected mail - instead, if not running under a tty, it redirects all the output into log files in /var/log
Regards
Jeff
| [reply] |
|
|
incidentally, we also use the singleton pattern for our Log class - and use this instead of print - it adds PID, date, time etc to all the lines, manages the logging detail level - (error, warn, general, debug, dump)
And the Log has a DESTROY that gets called when the singleton instance is destroyed - ie at the end of program, were we do some tidy-up, including emailing our support group if any ERROR or WARNING messages were logged.
It also provides a logFatal() method, which logs a message, sends an email and does a POSIX::_exit($exitval)
HIH
The reason we use POSIX::_exit() is that we are running on *NIX with the buggy GCC 2.95 - a task that runs for 5 minutes, creating hashes of about 200MB takes 20-30 minutes for garbage collection - the POSIX::_exit() exits immediately.
| [reply] |
|
|
All interesting suggestions so far - but we found too many issues with setting up DIE signal handlers for us to trust it in production
I have production code doing the type of logging you want to do (along with email notification of failure results, full stack traces and win32::eventlog support.) So im curious as to which "issues" you encountered. I attach $SIG{__WARN__} and $SIG{__DIE__} handlers, and ive had no problems.
---
demerphq
<Elian> And I do take a kind of perverse pleasure in having an OO assembly language...
| [reply] [d/l] |
Re: die function and notifications
by nimdokk (Vicar) on May 22, 2003 at 15:20 UTC
|
| [reply] |