Why use die?

B

Bill H

Just to preface the following so I don't get the "daily WTF" or
comments on code, I am not a "perl guru", I write code everyday in
perl, and though good at it, I will be the 1st to admit I don't know
everything.

I see examples like this in many programs, where you try to open a
file for write and you have a "die" statement after it:

open(TMP, '>'.$file) or die "Can't create file";

My question is, why would you use the "die" statement, ESPECIALLY in
the context of handling web based requests?

If you are controlling all of the inputs, filename, permissions, etc
and using flock, what is the need for a "die" statement?

It is not accomplishing anything, other than telling you that it could
not open the file, but again, if you control all the parameters then
it should be able to open the file everytime. If not, then it would
seem that the programmer did not anticipate everything that could stop
his program from working as expected.

Also, when perl is used as web based program, the die "some text"
isn't going to do anything except trigger a Server Error because you
do not have it in an HTML wrapper, unless you are using Carp, or it is
putting it in some log for later viewing (or I could be off on this,
if so let me know). Again, in the context of a web based program, the
die "some text", if shown to a visitor in a browser, is not going to
help the programmer, and may just help someone figure out how to hack
your program (especially if you are showing directory structures (ex:
die "Could not write $file /home/sites/www.domain.com/users/
webmaster")

It would seem more logical to have some error recovery routine instead
of a simple die. Somethig like:

open(TMP, '>'.$file) or try &errorHandlingRoutine;

Where if there was a failure it would execute the
&errorHandlingRoutine to attempt to fix the problem and then restart
the same line. The &errorHandlingRoutine could then "die" if it
couldn't fix it.

The perldocs say that you can have die almost do as I suggested, but
you can not return to the same line to try again.

Now knowing perl and the millions of module available out there,
something similar probably exists, but, if it does I have not seen
it.

Bill H
 
M

Mirco Wahab

Bill said:
I see examples like this in many programs, where you try to open a
file for write and you have a "die" statement after it:
open(TMP, '>'.$file) or die "Can't create file";
My question is, why would you use the "die" statement, ESPECIALLY in
the context of handling web based requests?

Exception handling is imho never trivial, in any language.

If the application logic is simple, if there's no
alternative to an "opened temp file", you have to
shut down the application. Why would you implement
exception handling if you don't have to?

Otherwise, there are quite a few ways in
Perl to do exception handling, also in
CGI- or mod_perl context.

Here are some thoughts on this topic
by somebody (which I found on the web):
http://axkit.org/docs/presentations/tpc2001/exceptions.axp/a.pdf


Do exception handling - if you have to,
don't do it, if you don't ...

Regards

M.
 
P

Peter J. Holzer

Just to preface the following so I don't get the "daily WTF" or
comments on code, I am not a "perl guru", I write code everyday in
perl, and though good at it, I will be the 1st to admit I don't know
everything.

I see examples like this in many programs, where you try to open a
file for write and you have a "die" statement after it:

open(TMP, '>'.$file) or die "Can't create file";

My question is, why would you use the "die" statement, ESPECIALLY in
the context of handling web based requests?

If you are controlling all of the inputs, filename, permissions, etc
and using flock, what is the need for a "die" statement?

You are never controlling everything. The file creation could fail
because the disk is full, because you've used too many file descriptors,
because the file server has just crashed and for a plethora of of other
reasons.

It is not accomplishing anything, other than telling you that it could
not open the file,

That's why it is good practice write

or die "Can't create $file: $!"

instead. Then you know which file you couldn't create and why (you might
also want to add a bit of context, so that you know where in your
program you tried to create that file and why).
but again, if you control all the parameters then it should be able to
open the file everytime. If not, then it would seem that the
programmer did not anticipate everything that could stop his program
from working as expected.

Even if I anticipate everything I may not be able to do anything about
it. Or it may not be worth the hassle.

Also, when perl is used as web based program, the die "some text"
isn't going to do anything except trigger a Server Error because you
do not have it in an HTML wrapper, unless you are using Carp, or it is
putting it in some log for later viewing (or I could be off on this,
if so let me know).

Yes, putting the error message into the log is probably what you want to
do in a web-based program, so that the programmer can later eximine the
log and find out what went wrong. Showing the message to the user is
often not very useful, since even if they care to report the error, they
will only report something like "it didn't work. No I don't remember the
message. I just closed the internet".
Again, in the context of a web based program, the
die "some text", if shown to a visitor in a browser, is not going to
help the programmer, and may just help someone figure out how to hack
your program (especially if you are showing directory structures (ex:
die "Could not write $file /home/sites/www.domain.com/users/
webmaster")

It would seem more logical to have some error recovery routine instead
of a simple die. Somethig like:

open(TMP, '>'.$file) or try &errorHandlingRoutine;

What is "try"?

Anyway, you can use eval to catch exceptions, so you can do something
like:


eval {
my $reply = fetch_content();
print "Content-Type: text/html\n";
print "\n";
print $reply;
}
if ($@) {
print STDERR "$0: $now: $$: $@\n";
print "Content-Type: text/html\n";
print "\n";
print friendly_error_message($@);
}

Then your code can die() anywhere within fetch_content or any function
called from it (even some library function not under your control) and
you still get both a good log file entry and a friendly message for the
user.
Where if there was a failure it would execute the
&errorHandlingRoutine to attempt to fix the problem and then restart
the same line. The &errorHandlingRoutine could then "die" if it
couldn't fix it.

The perldocs say that you can have die almost do as I suggested, but
you can not return to the same line to try again.

I don't see how your errorHandlingRoutine could do that either.

hp
 
A

Anno Siegel

Just to preface the following so I don't get the "daily WTF" or
comments on code, I am not a "perl guru", I write code everyday in
perl, and though good at it, I will be the 1st to admit I don't know
everything.

Always be prepared for code comments.
I see examples like this in many programs, where you try to open a
file for write and you have a "die" statement after it:

open(TMP, '>'.$file) or die "Can't create file";

The better examples show the file name and the system error in the
message:

open my $tmp, '>', $file or die "Can't create file '$file': $!";

(Also note use of lexical file handle and three-argument open())
My question is, why would you use the "die" statement, ESPECIALLY in
the context of handling web based requests?

Using "die" is just the generic way of error handling. The main point is to
deal with open() errors at all, instead of just ploughing on with an unopened
file handle. In practice, all kinds of variants can be seen, ranging
from simply
skipping intractable files

for my $file ( @files ) {
open my $fh, '<', $file or next;
# ...
}

to elaborate recovery schemes

if ( open ... ) {
# normal processing
} else {
# do something else instead
}

The salient point is *never* to expect an open() (or any critical
system call, for that matter) to succeed. All system commands
in Perl return a success indicator. Check it, always.
If you are controlling all of the inputs, filename, permissions, etc

Your program doesn't (necessarily) control all these.
and using flock, what is the need for a "die" statement?

It is not accomplishing anything, other than telling you that it could
not open the file, but again, if you control all the parameters then
it should be able to open the file everytime.

Disk full? Hardware failure?
If not, then it would
seem that the programmer did not anticipate everything that could stop
his program from working as expected.

Files are an external resource. The success of open() depends not only
on the program but also on things that happen while the code is unchanged.
It is never a good idea to assume a file that could be opened today can
be opened tomorrow.

On the other hand, if you *have* managed to think of everything, "or die"
doesn't hurt because it will never be called. Its presence doesn't stop
you from taking precautions.
Also, when perl is used as web based program,

Some perl programs are used that way (though "web-based" isn't quite
the right term), but not all by a long shot.
the die "some text"
isn't going to do anything except trigger a Server Error

That would depend on the relative placement of header-printing and
file-opening. OTOH, often "Internal Server Error" is exactly the thing
to announce when a file has gone missing (or has changed permissions,
or what have you).
because you
do not have it in an HTML wrapper, unless you are using Carp, or it is
putting it in some log for later viewing (or I could be off on this,
if so let me know).

The error log of the http server process, usually. Later viewing is what web
developers want when they learn that certain requests have started to fail.
Again, in the context of a web based program, the
die "some text", if shown to a visitor in a browser, is not going to
help the programmer, and may just help someone figure out how to hack
your program (especially if you are showing directory structures (ex:
die "Could not write $file /home/sites/www.domain.com/users/
webmaster")

Right. That's why the default behavior is not to show error messages
to users. Things like "use CGI::Carp qw(fatalsToBrowser)" are definitely
not meant for production but debug situations only.
It would seem more logical to have some error recovery routine instead
of a simple die. Somethig like:

open(TMP, '>'.$file) or try &errorHandlingRoutine;

Don't call subs with "&" unless you want the associated special effects.
What is "try"?
Where if there was a failure it would execute the
&errorHandlingRoutine to attempt to fix the problem and then restart
the same line. The &errorHandlingRoutine could then "die" if it
couldn't fix it.

Sure. That's often done. If you want to restart the statement, do something
like

errorHandlingRoutine() until open(...);

Here errorHandlingRoutine() *ought* to die if it doesn't find a promising
recovery, or you'll run an infinite loop.
The perldocs say that you can have die almost do as I suggested, but
you can not return to the same line to try again.

See above.
Now knowing perl and the millions of module available out there,
something similar probably exists, but, if it does I have not seen
it.

The standard formula

open(...) or die "...";

is just a reminder that open() can fail anytime. In view of the fact that
a user can "eval { sub_that_max_possibly_die( ...) };" to do their own
error processing, it is pretty much universally applicable. If you have
better error handling, use it. There's nothing sacred about "or die".

Anno
 
A

A. Sinan Unur

I see examples like this in many programs, where you try to open a
file for write and you have a "die" statement after it:

open(TMP, '>'.$file) or die "Can't create file";

As others have noted,

open $tmp_fh, '>', $file
or die "Cannot open '$file' for writing: $!";
My question is, why would you use the "die" statement, ESPECIALLY in
the context of handling web based requests?
Because,

If you are controlling all of the inputs, filename, permissions, etc
and using flock, what is the need for a "die" statement?

you do not control the universe. There are many things that can go wrong
at the most inopportune times (disk full, kernel bug, data corruption
etc etc).
seem that the programmer did not anticipate everything that could stop
his program from working as expected.

The programmer cannot anticipate everything but he can anticipate that
when a call might fail, it will occasionally fail.
Also, when perl is used as web based program, the die "some text"
isn't going to do anything except trigger a Server Error because you
do not have it in an HTML wrapper,

In real life, you get to decide how you communicate with the web site
visitor that an error has occurred. However, you als need the
information in the server logs to diagnose the problem. Depending on
your needs, it might be advisable to set up a script as the error
document handler to inform you of each error by email as well as
producing a human friendly error message for the web site visitor.

In toy programs, the important thing is to have checked for failure on
all calls that that might fail not how it is communicated to the end
user.
your program (especially if you are showing directory structures (ex:
die "Could not write $file /home/sites/www.domain.com/users/
webmaster")

The solution is not have these messages shown to the web site visitor.

In moderately complex web applications, I prefer to keep an application
log file in addition to the server log file.
It would seem more logical to have some error recovery routine instead
of a simple die.

A simple die is the least that can and ought to be done when a call that
is essential to the correct functioning of the program fails. That does
not mean you can't add niceties.
The perldocs say that you can have die almost do as I suggested, but
you can not return to the same line to try again.

I frequently use

eval {
something that can fail or die " ... $!"
something else that can fail or die " ... $!"
another call that can fail or die "... $!"
etc
};

if( my $fail_message = $@ ) {
write the failure to application log file
present user friendly error message
}

See also

http://www.stonehenge.com/merlyn/WebTechniques/col54.html

where Randal's script tries ten times to lock a file before giving up.

Sinan
 
A

Anno Siegel

Bill said:
I see examples like this in many programs, where you try to open a
file for write and you have a "die" statement after it:

open(TMP, '>'.$file) or die "Can't create file";

My question is, why would you use the "die" statement, ESPECIALLY in
the context of handling web based requests? [...stripped...]
Again, in the context of a web based program, the
die "some text", if shown to a visitor in a browser, is not going to
help the programmer, and may just help someone figure out how to hack
your program (especially if you are showing directory structures (ex:
die "Could not write $file /home/sites/www.domain.com/users/
webmaster")

For web scripts I use some like

my $ok=1;
open(TMP, '>'.$file) or sub {print "Can't create temporary
file.<br>Please contact webmaster"; $ok=0;}
if($ok) { # then write something to file}
# continue if possible

That won't work (and probably issue a warning). Apart from a missing
semicolon,
the code after "sub" will never be executed, so $ok would remain 1,
whatever the
outcome of open. If you changed "sub" to "do", things would look
better, but it's still
more involved than it has to be.

my $ok = open(...);
if ( $ok ) {
# write to file
} else {
print "Can't create temporary file.<br>Please contact webmaster";
}
# continue if possible

....but then the use of the variable $ok would be rather redundant.

Anno
 
X

xhoster

Bill H said:
Just to preface the following so I don't get the "daily WTF" or
comments on code, I am not a "perl guru", I write code everyday in
perl, and though good at it, I will be the 1st to admit I don't know
everything.

I see examples like this in many programs, where you try to open a
file for write and you have a "die" statement after it:

open(TMP, '>'.$file) or die "Can't create file";

My question is, why would you use the "die" statement, ESPECIALLY in
the context of handling web based requests?

So that if something goes wrong, you know what it is.
If you are controlling all of the inputs, filename, permissions, etc
and using flock, what is the need for a "die" statement?

If you never make mistakes, feel free to dispense with die, as well as
warnings and strict. Just don't expect to get much sympathy from those
of use who don't assume we are perfect and who don't assume you are
perfect, either, but are often called on waste our time tracking down the
mistakes made by people who do apparently think they are perfect and
therefore didn't make provisions for their own errors.
It is not accomplishing anything, other than telling you that it could
not open the file, but again, if you control all the parameters then
it should be able to open the file everytime. If not, then it would
seem that the programmer did not anticipate everything that could stop
his program from working as expected.

Like other people. And the Spanish Inquisition. No one ever thinks of
that.

Also, when perl is used as web based program, the die "some text"
isn't going to do anything except trigger a Server Error because you
do not have it in an HTML wrapper, unless you are using Carp, or it is
putting it in some log for later viewing (or I could be off on this,
if so let me know).

If you are using CGI::Carp, then you are wrong.
Again, in the context of a web based program, the
die "some text", if shown to a visitor in a browser, is not going to
help the programmer,

Unless the visitor happens to be working in the next cubicle over and pops
his head up and says "Hey, come look what just came up on your page." Or
if the visitor is, you know, you. Or if the visitor contacts you, as
CGI::Carp can be configured to instruct them to do.
and may just help someone figure out how to hack
your program (especially if you are showing directory structures (ex:
die "Could not write $file /home/sites/www.domain.com/users/
webmaster")

If you run a site that anyone really wants to hack into and the only thing
keeping your web site safe is the inability of a user to guess any of those
words above, then you are pretty much screwed anyway.
It would seem more logical to have some error recovery routine instead
of a simple die. Somethig like:

open(TMP, '>'.$file) or try &errorHandlingRoutine;

That would be more logical only if errorHandlingRoutine actually does
something more logical. Often, there just isn't anything more logical
to be done. When there is, go ahead and do it. You have my permission,
to the extend you need it.
Where if there was a failure it would execute the
&errorHandlingRoutine to attempt to fix the problem and then restart
the same line. The &errorHandlingRoutine could then "die" if it
couldn't fix it.

Sure. But now you have jumped from "Nothing should ever go wrong, ever,
and there is no reason to think it ever could" to "When something does go
wrong, obviously you should magically be able to fix it." Why go from
one extreme to the other without even considering stopping somewhere along
the way?
The perldocs say that you can have die almost do as I suggested, but
you can not return to the same line to try again.

Now knowing perl and the millions of module available out there,
something similar probably exists, but, if it does I have not seen
it.

In the rare case in which I have something better to do than just die
in the event of an open failing, I do it. It had never occurred to me
to look for a module that would tell me what *I* should do when *my* open
fails.

Xho
 
M

Michele Dondi

For web scripts I use some like

my $ok=1;
open(TMP, '>'.$file) or sub {print "Can't create temporary file.<br>Please
contact webmaster"; $ok=0;}
if($ok) { # then write something to file}

Pardon me for pointing out, but if you really do this, then you're
doing something utterly wrong. The sub code is never executed on
failure. You would have to dereference it with ->(). Even so, it looks
really awkward.


Michele
 

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

Similar Threads

die alias 15
PHP failed to create file 13
Why did PUGS die? 2
Should I EVER use " || die "? 7
sysopen - die only if EBUSY? 3
Using END and the die function 14
Merge files 1
Positioning student result by ranking grade 1

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top