Beefy Boxes and Bandwidth Generously Provided by pair Networks
Think about Loose Coupling

Re: Re (tilly) 3: Seeking Feed back

by orkysoft (Friar)
on Jul 05, 2001 at 16:53 UTC ( #94082=note: print w/replies, xml ) Need Help??

in reply to Re (tilly) 3: Seeking Feed back
in thread Seeking Feedback on Chat Program (was Seeking Feed back)

Well, my CGI program was installed in a controlled environment, where errors should be very rare, and users were generally _very_ clueless. I can't just have my program die on them! Instead, my program would skip the file operation in question, but log an error, and display an error message with a possible solution, print out the rest of the page layout, and then end at the same spot the program would normally.

Maybe it's a matter of taste, but I just don't like the or die construct, it doesn't give me the ability to neatly and readably handle the exception.


sub display_values_from_file { my $filename = shift; if(open FILE, "<$filename") { # check return value of open flock FILE, 1; while(<FILE>) { print &process_line_from_file; } close FILE; } else { print "The file could not be opened. Please try again later!"; log_error "open $filename : $!"; } } # main program ... # do something print $some_nice_html; display_values_from_file "/foo/bar.baz"; print $rest_of_html_page; # end

This way, when an error occurs, the user will be informed of the error, and all the links the user would need would still be there.

Replies are listed 'Best First'.
Re (tilly) 5: Seeking Feed back
by tilly (Archbishop) on Jul 05, 2001 at 17:52 UTC
    I was not commenting on the error being silent or not.

    I am commenting that your initial version failed to log critical information that would make it possible to debug the problem later. And no matter how controlled the environment may be, you are not going to convince me that you won't ever have bugs to track down.

    I am glad that your current example does that better. It does not do it well enough to make me happy, but it is better.

    Here is a better version of the same thing that you have:

    sub ret_read_fh { my $filename = shift; my $fh = do {local *FH}; unless(open($fh, "< $filename")) { log_error("open '$filename': $!"); return; } unless(flock($fh, 1)) { log_error("flock '$filename': $!"); return; } return $fh; } sub display_values_from_file { my $fh = ret_read_fh(shift); if ($fh) { while(<$fh>) { print process_line_from_file($_); } } else { print "Error opening file. Please try again later!"; } }
    Why better? Well suppose that some bright sysadmin gets the idea of having your data mounted from another machine over NFS. (This is not an unreasonable thing for a sysadmin to have reason to do.) With the revised version you will get notified that flock no longer works. With the original version the error would be silent until someone noticed sporadic loss of data over 6 months and thought to wonder why. (At which point you read your code and have no a clue where it could fail.)

    My points?

    1. Don't trust system calls to succeed.
    2. Make sure that when they go wrong you have enough information to debug.
    3. Realistically you have a choice. Make errors fatal, or else encapsulate code which needs to handle errors. After all when you find a new possible cause of errors you do not want handling it to be harder than necessary.
    Also a middle ground to consider is to make errors be fatal, but make sections with fatal error handling be trapped by an eval block. That makes breaking out on large numbers of possible errors easy to implement, while not interfering with your ability to handle the exception for the user.

      I agree with your NFS/flock point. That could still go wrong if there were to be an NFS system (or a Windows machine for that matter).

      (My 'initial version' was just something that looked like the code I used. I might have forgotten to log the actual error message there, but I wasn't coding 'literal' there.)

      But apart from that and your localised filehandle, your code looks very much like mine, with just some inverted logical structures.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://94082]
and the fire pops...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (7)
As of 2018-06-20 04:35 GMT
Find Nodes?
    Voting Booth?
    Should cpanminus be part of the standard Perl release?

    Results (116 votes). Check out past polls.