in reply to Re^2: Troubleshooting perl runtime errors
in thread Troubleshooting perl runtime errors
Yeah, with 5.8.x, the warnings are indistinguishable. And thanks for pointing out that the empty array will also create that error: my errcheck_array() didn't handle the empty array condition.
Further, while both my method and the BrowserUk/stevieb method will help you find what's wrong, neither will help sanitize the input to prevent the warning in a live-system (for example, if you need your debug logging live until the unlikely data triggers it, but you still need the production code to set a reasonable value for $EVmsg): it's safer in production code to try to sanitize the input, to prevent such a condition from affecting your users. For that, you could wrap an error-checker-and-sanitizer around the sprintf command, or otherwise sanitize before running the sprintf. This example has a wrapper sprintf_prevent_error() and a sanitize() function which cleans and logs, but keeps the sprintf separate:
use warnings; use strict; use Log::Any qw($log); use Log::Any::Adapter ('File', './debug.log', log_level => 'debug'); sub sprintf_prevent_error { my $format = shift; my @a = @_; # if there isn't a format, log an error message and return an erro +r string # might want to return undef instead, and check $EVmsg for undef + before blindly doing anything else with it... unless(defined $format) { $log->debugf("sprintf('%s',%s): format is not defined", $forma +t, \@_); return "<WARNING: sprintf format not defined>"; } # if there aren't any arguments, the array is undefined; log an er +ror message and return an error string # might want to return undef instead, and check $EVmsg for undef + before blindly doing anything else with it... unless(@a) { $log->debugf("sprintf('%s',%s): array is empty", $format, \@_) +; return "<WARNING: array is empty>"; } # count the number of undefined elements in input array, and log t +he error message # but _don't_ return; we will sanitize the inputs and continue t +o create the sprintf my $count = grep {!defined} @a; $log->debugf("sprintf('%s',%s): sanitizing %d undefined values", $ +format, \@_, $count) if $count; # sanitizes the input: replace any undefined elements with the emp +ty string $_//='' for @a; # return the final sprintf of the sanitized input sprintf $format, @a; } sub sanitize { $log->debugf("sanitize(%s): calling", \@_); unless(@_) { # log and return if there's nothing to sanitize $log->debugf("sanitize(%s): nothing to sanitize", \@_); return; }; my $count = grep {!defined} @_; # count the undefined argument +s $log->debugf("sprintf(%s): sanitizing %d undefined values", \@_, $ +count) if $count; $_//='' for @_; } foreach my $hr ( [qw(a b c)], [d => undef, e => undef, 'f'], [qw(x y z +)], [] ) { my @HR = @$hr; my $DIcas_text = @HR ? '%s' . ',%s'x$#HR : 'empty array format'; my $EVmsg = sprintf_prevent_error($DIcas_text, @HR); print "STD OUTPUT> $EVmsg\n"; $EVmsg = sprintf_prevent_error(undef, @HR); print "STD OUTPUT> $EVmsg\n"; sanitize($DIcas_text, @HR); $EVmsg = sprintf($DIcas_text, @HR); }
|
---|