Remember to store errors!

In Perl, when you get an error, there are magic globals that the interpreter sets to the value of that error. If you’re going to do any other work before reporting the error, save those variables!  Work almost got this right…

Here’s pseudo code of what I found at work today:

$ok = link("$src/$file", "$dst/$file");
unless($ok) {
    my $log = $!;
    log_error_in_database($log);
    send_error_in_email($!);
}

See the error?  The coder saved the error from $! in $log, and then passed it to the DB to store it.  The DB (which no one knew existed) had all the right errors.  Writing to the DB changed $! to a harmless non-error.  It wound up being “Resource temporarily unavailable” or whatever numeric value that is.  It’s meaningless, though, because it was set by calling some other stuff in the DB handling function.

Then, the code tries to e-mail it.  Clearly the DB was added later, as it didn’t use the copy they saved there, and used $!, sending the useless value to us in e-mail where we all looked at it.

(Edit: A sharp commenter suggested I actually show the fix, which is an excellent idea!)  Instead of storing your error, then forgetting to use it, use the stored error message in both places:

$ok = link("$src/$file", "$dst/$file");
unless($ok) {
    my $log = $!;
    log_error_in_database($log);
    send_error_in_email($log);
}

Another alternative would be to use local on $!, but that’s not as sound, because every function you call also has to do the same, and it is hard to tell what module or library you use might get it wrong.  Saving a copy of $! for your code to use later will be safer.

The good news is that I eventually found, and realized the values were in the DB and looked there so I know what was going on and can try and make progress.

This is actually cleaner and simpler than the real code.  The real code actually did check the results of link(), which is good!  It doesn’t check mkdir() or chdir() anywhere, though…  It’s not the worst Perl I’ve ever seen, but it’s on the list of contenders.

I really, really want to replace this code with something that is less painful.  I have a nice, new Modern Perl version well underway.  We’ll see if management lets me finish and deploy it!

Tags:

2 Responses to “Remember to store errors!”

  1. Gabor Szabo says:

    Nice.

    It would be even nicer if you added the recommended fixed version. You know, for people who are still learning this.

Leave a Reply