trapping errors using $!

J

John

Hi

This part of code is in a web service so there is no output to screen.
I've turned off printing to standard error.

open STDERR,'>/dev/null';

.....
read (STDIN,$request,$length);
if ($1 > 0) {$response=$error1};

Would the above condition trap any error?

Regards
John
 
P

Peter Makholm

John said:
open STDERR,'>/dev/null';

....
read (STDIN,$request,$length);
if ($1 > 0) {$response=$error1};

I guess that you meant to use $! here?
Would the above condition trap any error?

No, $! is at most true for the last system call you've made. So this
construct would only trap errors from you read call.

//Makholm
 
C

C.DeRykus

Hi

This part of  code is in a web service so there is no output to screen.
I've turned off printing to standard error.

open STDERR,'>/dev/null';

....
read (STDIN,$request,$length);
if ($1 > 0) {$response=$error1};

Would the above condition trap any error?

Hm, I'm not sure what "any error" means in this
context. (also the use of $1 isn't clear to me)

You could check with something such as:

my $nread = read( STDIN, $request, $length );
unless (defined $nread) {
$response = "read error: $!";
...
}

This'd pick up the read error only though.

perldoc -f read
 
S

sln

Hi

This part of code is in a web service so there is no output to screen.
I've turned off printing to standard error.

open STDERR,'>/dev/null';

....
read (STDIN,$request,$length);
if ($1 > 0) {$response=$error1};

Would the above condition trap any error?

Regards
John

Assuming you meant
$cnt = read ($handle, $buffer, $length);
if (!defined ($cnt) ) {
print "Error reading from file: $!\n";
}

But, and I don't know if this is true, from some module
I looked at, dated a few years ago, it mentioned defined isin't
always an error check on some platforms.
Quote:
" read is supposed to return undef on error, but on some platforms it
seems to just return 0 and set $!"

Then he does some wrapper read sub.
The jist boils down to this:

{
local $!;
$cnt = read ($handle, $buffer, $length);
if (!$cnt && $! ) {
print "Error reading from file: $!\n";
}
}

This would seem to cover both
($cnt as undefined or $cnt is zero) and $! is not empty

Not sure about this.
Usually just a
defined(read($fh,$buf,$length)) or croak "Read caused an error: $!";
will do ok.

-sln
 
J

John

Assuming you meant
$cnt = read ($handle, $buffer, $length);
if (!defined ($cnt) ) {
print "Error reading from file: $!\n";
}

But, and I don't know if this is true, from some module
I looked at, dated a few years ago, it mentioned defined isin't
always an error check on some platforms.
Quote:
" read is supposed to return undef on error, but on some platforms it
seems to just return 0 and set $!"

Then he does some wrapper read sub.
The jist boils down to this:

{
local $!;
$cnt = read ($handle, $buffer, $length);
if (!$cnt && $! ) {
print "Error reading from file: $!\n";
}
}

This would seem to cover both
($cnt as undefined or $cnt is zero) and $! is not empty

Not sure about this.
Usually just a
defined(read($fh,$buf,$length)) or croak "Read caused an error: $!";
will do ok.

-sln

Thanks, gentlemen, for the various comments.
I'll try some this weekend.

At the moment I'm using :

eval {read (STDIN,$request,$length);};
if ($@ ne '') {$response=$error1}

which appears to be working.

Regards
John
 
S

sln

At the moment I'm using :

eval {read (STDIN,$request,$length);};
if ($@ ne '') {$response=$error1}

which appears to be working.

Regards
John
That will trap fatal errors from read.

An example is an undefined filehandle.
For some reason, file i/o does not take kindly
to undefined'ness when a handle is passed around
internally so much. Theorehtically, that may cause
a program crash if subcode does not check for null
pointers. Believe me there is alot of C code that
is buggy. So all the entry points are checked for undef
filehandles and die serves as a warning that your
program is working on borrowed time.

There are other less aggredious errors, secondary
level, or non-fatal errors that do not generate an
exception like die. These return an undef result on
i/o operations. An example is that you opened a filehandle
but did not check if it 'failed'. In reality, you sucessfully
allocated a correct filehandle but does not have a valid file
descriptor. This does not cause Perl's internal C code to
generate a fault as a null pointer would.

But how can you trap both kinds of errors, fatal/non-fatal?
In the real world, you don't want to trap fatal errors though,
you want to let them gracefully stop your program. This gives
you an oppurtunity to fix your code, which is broken.

I don't recommend trapping fatal errors, but if you want to
trap all errors (fatal/non-fatal) below is one way to do it.

-sln
---------------------------------------------------
use strict;
use warnings;

my ($buf,$length) = ('',5);

# Invoke error #1, NON - FATAL error on read.
# File doesen't exist, however, $fh is valid
open my $fh, '<', 'notexists.txt';

# Invoke error #2, FATAL error on read
#my $fh;

open STDERR, '>errors.txt';

{
local $!;
my $status = eval { read ($fh, $buf, $length) };
$@ =~ s/\s+$//;
if ($@ || (!$status && $!)) {
print "Error in read: ". ($@ ? $@ : $! ). "\n";
}
}

print "More code ...\n";

exit;

__END__
 
E

Eric Pozharski

Well, yes, it works as long as nothing goes wrong. 'read' doesn't throw
an exception on error (unless you 'use Fatal' or 'use autodie', which I
would probably recommend nowadays), so you are just completely ignoring
any possible errors.

I would say: if you're going for B<read> then you know what you're
doing.

# ignoring eof and counts
defined read STDIN, $request, $length or
die $!;
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,052
Latest member
LucyCarper

Latest Threads

Top