hello list,
i am creating a general purpose module and am confronted with a
small design problem for handling errors.
consider this code for locking a file (from marekm's shadow
passwd suite for linux)
sub __lckfile ($)
{
my $file = shift;
my ($pidfile, $lockfile) = ("$file.$$", "$file.lock");
my $retval;
sysopen (FH, $pidfile, O_WRONLY | O_CREAT || O_EXCL, 0600) ||
return;
print FH "$$\x00" || return;
close (FH) || return;
# keep looping until we lock or return inside loop
until (link ($pidfile, $lockfile)) {
my $pid;
sysopen (FH, $lockfile, O_RDONLY) || goto ERR_RET;
read (FH, $pid, 2048) || goto ERR_RET;
close (FH) || ERR_RET;
# if process is alive unlink opened files and return undef
goto ERR_RET
if (kill (0, $pid));
unlink ($lockfile);
}
# if the link count of $passwd_pidfile is 2 then we have succeded
# this locking algorithm is the only safe one over NFS as flock, fcntl
# may fail miserably.
$retval = __check_link_count ($passwd_pidfile);
unlink ($passwd_pidfile);
return $retval;
ERR_RET:
unlink ("$passwd_pidfile");
return;
}
there are many points at which the code could fail, during which we
return false to indicate failure. the calling function could then indicate
error to its caller as it wishes. this is one alternative and its advantage
is flexibility, while the downside is loss of information.
another is to call
die ("syscall (argument): $!\n")
for every failure condition. the second obviously provides more debugging aid
and would be very helpful in the event of a problem. having the caller function
invoke die would be helpful too, but i would lose information on what function
cause the error. however the user of this module is faced with coding eval {}
blocks to handle exceptions, and could be considered irritating. while i am in
favour of the second style, i have a few questions.
which is more widely in production quality perl modules and why ? are there
other alternatives. since i keep reading about standard perl idioms, are there
any other standard ways of handling errors in general purpose modules and
their utility functions. would something like a die () call if debugging is
set be more appropriate ? what i want here is opinions of experienced coders,
who have been in both situations (that of a module coder wanting to offer
the best interface, and that of a user dissatisfied with the error handling
of a certain module)
karthik
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]