Re: Error Handling Misconception
by bobn (Chaplain) on Sep 03, 2003 at 22:16 UTC
|
if the eval fails, it your function probably also returned a false value, which caused your while loop to skip the if ( $@ ) code.
--Bob Niederman, http://bob-n.comAll code given here is UNTESTED unless otherwise stated.
| [reply] [Watch: Dir/Any] |
|
my $value = eval { $object->next_value() };
if ($@) { print "BLAH!\n"; }
print $value, "\n";
...and no output to screen. | [reply] [Watch: Dir/Any] [d/l] |
|
my $object = new wierd;
my $value = eval { $object->next_value() };
if ($@) { print "BLAH!\n$@\BLAH!\n"; }
print $value, "\n";
package wierd;
sub new { bless {}, shift}
sub next_value
{
die "badness";
}
Produces:
BLAH!
badness at ./tstprog.pl line 13.
BLAH!
Are you sure you're in a situation where you can see what's printed? What happens when the routine works and $value is something printable?
--Bob Niederman, http://bob-n.comAll code given here is UNTESTED unless otherwise stated.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
Make sure a header goes out to the browser before the die message. If your code dies before it had the chance to print the header, then you will likely get an error. I susally just do this at the beginning of my cgi:
print "Content-type: text/html\n\n";
Hope that helps,
selk | [reply] [Watch: Dir/Any] [d/l] |
|
I feel stupid...
Are you sure you're in a situation where you can see what's printed? What happens when the routine works and $value is something printable?
Once I took it out of CGI and put it in a text-file to get the minimum error, it worked. There's a bug somewhere in my CGI that I'll have to track down, but this is working fine now. Thank you muchly.
| [reply] [Watch: Dir/Any] |
Re: Error Handling Misconception
by gjb (Vicar) on Sep 03, 2003 at 22:27 UTC
|
To catch die's with eval, the eval block must be terminated with a semi-colon.
So you'd better be off rewriting the while as
for (;;) {
my $value = eval { $object->next_val() };
if ($@) {
print "Error: $@\n";
next;
}
last unless $value;
# do something useful...
}
Hope this helps, -gjb-
Update: Althought chromatic puts it very politely, he's dead right: the semi-colon stuff above was nonsense. Thanks chromatic for making me think twice.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
sub dies
{
die "That's it!";
}
if (eval { dies(); 1 })
{
print "No death!\n";
}
else
{
print "Death caught: $@\n";
}
| [reply] [Watch: Dir/Any] [d/l] |
|
You probably got that idea about the semi-colon from the Error module which uses sub refs to implement a try/catch syntax. The sub refs do require a semi-colon.
| [reply] [Watch: Dir/Any] |
Re: Error Handling Misconception
by line_noise (Sexton) on Sep 04, 2003 at 13:48 UTC
|
If you haven't already, you might want to check out CGI::Debug. All you have to do is
use CGI::Debug;
and you get all of the CGI vars and evalish errors in a report format displayed inline at the bottom of your page. It saves a lot of time debugging the kind of error handling you're working on.
| [reply] [Watch: Dir/Any] [d/l] |
Re: Error Handling Misconception
by kesterkester (Hermit) on Sep 04, 2003 at 13:04 UTC
|
I'm interested in what advice the monks can give on the following
form of eval error catching-- I picked it up at work
and have been using it for a while, with pretty good
success. I use programs that run other programs at work,
and this displays which program died when a die
happens.
eval { main () };
print STDERR "# $0: ", $@
and exit 1
if $@;
exit 0;
sub main {
# do everything
...
}
I don't use the try/catch form of eval much, although
it does seem to work with the above:
eval { main () };
print STDERR "# $0: ", $@
and exit 1
if $@;
exit 0;
sub main {
my $val = eval { test_sub () };
print "hi" if $@;
}
sub test_sub { die "test_sub dies" }
prints "hi", not "# <programname>: test_sub dies", as I expected.
Any advice? Could this lead me to shoot myself in the foot
later on? Thanks much.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
Why did you expect it to do anything else? Your inner eval caught the first exception, but instead of propagating it, you discarded it and printed "hi". The outer eval saw no error, becauase the iner eval ignored it.
This program behaved exactly as expected.
If you wanted the this to do something else, the followingin (untested) would have been better:
sub main {
my $val = eval { test_sub () };
die "hi" if $@;
}
--Bob Niederman, http://bob-n.comAll code given here is UNTESTED unless otherwise stated.
| [reply] [Watch: Dir/Any] [d/l] |
Re: Error Handling Misconception
by aquarium (Curate) on Sep 04, 2003 at 13:28 UTC
|
if i understand $@ correctly: it contains an error message for the "most recent" statement. in this case it's supposed to be the eval, but instead it's the assignment, which resets $@ to null. so the loop should be while (eval { my $value = $object->next_val() }) {
# do cool stuff
}
print "Error: $@\n" if($@);
| [reply] [Watch: Dir/Any] [d/l] |
|
According to perlvar,
- $EVAL_ERROR
- $@
-
The Perl syntax error message from the last eval() operator.
If $@ is the null string, the last eval() parsed and executed
correctly (although the operations you invoked may have failed in the
normal fashion). (Mnemonic: Where was the syntax error ``at''?)
-
Warning messages are not collected in this variable. You can,
however, set up a routine to process warnings by setting $SIG{__WARN__}
as described below.
-
Also see Error Indicators.
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: Error Handling Misconception
by Roger (Parson) on Sep 05, 2003 at 02:14 UTC
|
The while loop would fail if your eval { $object->next_val() } returns undef (or fails), thus it will never get into the error checking code when the evaluation fails. If you switch to a do { eval; check; ... } while loop, then the error handling will be effective. | [reply] [Watch: Dir/Any] [d/l] [select] |