I run into two problems using CGI. Errors during execution caused by something and errors in parsing caused by me and fat fingers. The former creates a browser on the other end that has receiv ed half of a page of HTML. The later creates a user starting at a 500 error with no context. I fixed this tow ways:
- I buffer all output to the browser in a string and then flush that buffer to STDOUT before exiting. If I encounter a problem during running I can output a boilerplate html page with some info.
- Lighttpd executes a wrapper who runs the correct file. This can be expensive with cycles, but allows me to capture errors I've created.
In my module that manages web sessions I have a log() function that looks similar to this
log {
my @args = @_;
my $fmt = shift @args;
open my $fh, ">>", "/var/log/error.log" or return;
printf {$fh} $fmt, @args;
close $fh;
return;
}
The open, append, close logic is compatible with log rotation. Anything capture on STDERR when executing the real CGI script wil be written there.
The CGI script can also use the same function to write to the log file.
To use the buffering idea you have to capture the output of any methods you use in CGI that want to print to STDOUT. For years, the only methods I used in the CGI module was the ones to retrieve the form values. It is possible that CGI has its own buffer with flush.
I'll do something like this
{
my $buffer = "";
sub _print {
my @args = @_;
$buffer .= sprintf shift @args, @args;
return;
}
sub _flush {
my $content = $buffer;
$buffer = "";
local $| = 1;
print $content;
}
}
_print($cgi->header( -type => .... ));
......
_flus();
|