Release of Nagios::Plugin::DieNicely with surprises

Posted on 28/05/

I released version 0.04 of Nagios::Plugin::DieNicely with an interesting bug fix that has generated an interesting surprise.

First: the bug: when debugging a script that uses N::P::DN, the debugger would exit inmediately:

bender:~$ perl -d check_something

Loading DB routines from perl5db.pl version 1.3
Editor support available.

Enter h or `h h' for help, or `man perldebug' for more help.

...[SUPRESSED TEXT]...

CRITICAL - Can't locate Term/ReadLine/Gnu.pm in @INC (@INC contains: t/lib/ lib/ /etc/perl /usr/local/lib/perl/5.10.0 /usr/local/share/perl/5.10.0 /usr/lib/perl5 /usr/share/perl5 /usr/lib/perl/5.10 /usr/share/perl/5.10 /usr/local/lib/site_perl .) at (eval 4)[/usr/share/perl/5.10/Term/ReadLine.pm:320] line 1.
Nagios::Plugin::DieNicely::_nagios_die(lib//Nagios/Plugin/DieNicely.pm:35):
35:         die @_ if $^S;
Can't locate object method "new" via package "Term::ReadLine" at /usr/share/perl/5.10/perl5db.pl line 5998.
bender:~$

Strange... and also... if you did use Math::BigInt try => 'GMP'; with N::P::DN enabled, the script would die to...

The root cause was a bit harder to detect, until I ran into documentation about the $^S variable (that N::P::DN uses to know if the exception has generated in an eval {} or not). I originally though that it could only have two values, but as stated in perldoc: It has three!

So... It looks like the debugger throws an exception while loading... And playing around with why using N::P::DN with Math::BigInt was failing too I started suspecting that the problem was with programs that dynamically load classes. So a fast test case:

bender:~$ perl -MNagios::Plugin::DieNicely -e"BEGIN { eval { die 'X' } }"
CRITICAL - X at -e line 1.
revealed everything. Note that although the exception is raised in an eval... N::P::DN will intercept it, think it wasn't in an eval block and exit in a Nagios friendly way. This is because when you're in a BEGIN block, and the code dies: $^S will be undef. It doesn't matter if it's in an eval or not as
bender:~$ perl -I lib/ -MNagios::Plugin::DieNicely -e"BEGIN { die 'X' }"
CRITICAL - X at -e line 1.
demonstrates. So there is no alternative. I just to propagate the exception... If it is catched, then everything will be OK. If it's not... then the plugin will die in a Non-Nagios compatible manner: no output, and exit code 255

So I fix N::P::DN, program the tests and get a surprise!
bender:~/Nagios-Plugin-DieNicely-0.04$ perl -I lib/ -I t/lib/ t/bin/notok_using_die_in_begin.t
DIED!!! at t/lib//DieModule.pm line 4.
BEGIN failed--compilation aborted at t/lib//DieModule.pm line 5.
Compilation failed in require at t/bin/notok_using_die_in_begin.t line 4.
BEGIN failed--compilation aborted at t/bin/notok_using_die_in_begin.t line 4.
bender:~/Nagios-Plugin-DieNicely-0.04$ echo $?
9
bender:~/Nagios-Plugin-DieNicely-0.04$

It's exiting with exit code 9. I thought: "that's strange... but OK... Nagios doesn't matter between exit code 255 and 9...". So I upload the module to CPAN, and get yet another surprise! SOME tests start being reported as FAIL in CPAN testers

And the test that is failing:

#   Failed test 'Exit code 9 for ./t/bin/notok_using_die_in_begin.t'
#   at t/002_test_outputs.t line 87.
#          got: 255
#     expected: 9
# Looks like you failed 1 test of 108.

So now the question is: What's happening? It's doesn't seem critical, but I don't like my tests failing, and I would want to at least understand what's going on. Any suggestions?