When Good Scripts Go Bad By Bill Zink|
WE'VE ALL BEEN there. After hunting through all the free script sites
on the web for the perfect script, you finally find it, just what you're looking for.
all the instructions in the README.TXT file, carefully upload it to your server,
permissions, and presto!
Error. There's nothing on the page.
Unluckily for us, CGI errors tend to be cryptic, frustrating, and downright unhelpful. One of the last
things a webmaster wants to see when he executes his script is the foreboding 500 error. It's easy to almost expect
getting that error sometimes, as it comes up so often, being the catch-all error message for countless, miniscule errors
that pop up in the code. Here are a few things to check for when that script just won't work.
It's the line-break, stupid. - This mistake just goes to show that errors can pop up anywhere, even the very first line of
the stupid code. This one had me stumped for a long time- I was writing scripts that mystically either worked or didn't
work, and I couldn't ascribe their success or failure to anything I was doing. Sometimes they worked, sometimes they
didn't. After a hellish two weeks, I remembered that the shebang line (that is, #!usr/bin/perl or whatever) required a
line-break after it. Half relieved and half angry at myself, I resolved to manually put in several line breaks after the shebang
line from then on. I do this by cutting-and-pasting the actual solid-block symbols from Notepad into the actual perl document.
It sounds like a waste of time, but I still do it, and sometimes it saves the day.
Choose the path more travelled - Navigating the vast deserts of the Sahara is, I suppose, an arduous task, but
child's play compared to consistently navigating UNIX paths on your server. Always check that your relative paths do not
begin with a slash, and do not reference the folder they are already in. By this, I mean if you have a script mail.pl
in your CGI-BIN that calls the external file data.log that is also already in the CGI-BIN, make sure the path
is not cgi-bin/data.log, but simply data.log. If a script just won't work no matter what you do, you might
as well eliminate a whole category of errors by making all your paths absolute. This is how problems are solved, by
process of elimination.
"Permissions are like Communism, in that they're both simple concepts that, in
practice, quickly get out of hand."
No comment? Think again. - Speaking of process of elimination (sounds like a great Grisham title, eh?), you can do
just this by putting a comment mark (#) in front of questionable lines of code. Keep doing this with more and more lines,
checking to see if the script works after each few lines you comment out. When it finally does work, that means (probably)
that the last few lines you commented out were the culprits. This is really a great little trick.
We all live in an error subroutine - Sorry about that. But error subs are a great help in pinpointing trouble
code. One terrible thing about Perl is its tendency to neglect to tell us when an external file fails to open for
one reason or another. Perl is hush-hush about this, but later on when you try to access that file, Perl treats you
like a criminal. The solution is an error sub that runs only if the file fails to open:
open (log,".../.../file.log") || &error_sub
But Steve's mom said he could! - Permissions. Like communism, in that they're both simple concepts that, in
practice, quickly get out of hand. Permissions are simple enough when you're just uploading a script to your server, and chmod'ing
it, but its a whole 'nother story when your script is creating user setting files for your visitors, and the server thinks the
scripts themselves are the owners, and you're a sneaky hacker with a death wish. Always consider that permissions may be
the problem when things aren't working, especially when dealing with external files. Also, remember that files should always
be uploaded in ascii transfer, never binary. Set your FTP client up to default to ascii now, and save yourself the cash for the case
Confusion Sucks - One of the nightmares
of enormous scripts is getting variables confused. What was this called, was this capitalized, was that one global or local? When writing or modifying scripts,
things you thought would be simple get out of hand really quick. The best course is to type:
Doing this will force you to do what I'm about to suggest you do- always declare your variables and subs up front, right away
before ever using them in code. Never call a sub without the & prefix or the parenthesis suffix. There are so many reasons to do
this I can't list them all here. Suffice to say, even if your script works fine now, in a year or two you'll make a minor change,
and POW, the lights go out. How's that, you ask?
A while back, I wrote a complicated script that took an entire week of coding. It worked fine, I was happy. Then, six months later,
someone at my company added a tiny little subroutine, and like I said, POW, the lights went out, and guess who had to carry
the flashlight down to the cellar to reset the breakers? Me, of course. After nearly a week of clueless attempts to fix it, it turned out that
I hadn't declared my variable "$unitCost" at the script start, I had just used it in a calculation to initialize it. Well, the guy who modified the script after
me, it turns out, had decided to build a new sub called "unitCost" which had, inadvertently and because of my sloppiness,
wreaked havoc, as the interpreter confused the variable and the subroutine. So it goes.
Think locally, act locally - Debugging Perl will always be painful, but one if you're able to download the perl interpreter on your machine (check out www.perl.com) and debug it locally, takes some of the sting out. Good luck and happy coding! AT