I am using Net::LDAP (p5-perl-ldap-0.28) on a FreeBSD 4.9 server with Perl 5.8 (perl-5.8.2_5). In general, I have Net::LDAP working well, but every once in a while I get an error. The problem is that I should never see this error I think.
Here is what I do:
1. I connect to the LDAP server. I save this connection in a cache for reuse later on. 2. I do a $mesg = ...search() 3. I verify that $mesg is defined. 4. I run $mesg->code.
Every once in a while I get this error message:
Can't call method "code" on an undefined value at xxx.pl
But I just verified that $mesg was defined! Why does this happen? And how should I be checking for this kind of error?
Following is more or less the code I'm using. Any help is appreciated. Also, before continuing, for debugging I tried to use Data::Dumper. The weird thing is that I get no output whatsoever if my LDAP result has one or more entries, but I do get debug output if I have no result set.
use Net::LDAP; ... if (defined $ldap_cache{"$rcpt_to_domain"}) { $ldap = $ldap_cache{"$rcpt_to_domain"}; } else { my $ldap_port = 389; $ldap_port = $ldap_info->{"ldap_port"} if (length($ldap_info->{"ldap_port"}) > 0);
$ldap = Net::LDAP->new($ldap_info->{"ldap_server"}, port => $ldap_port, timeout => 5, onerror=>'undef') or die "Can't connect to ".$ldap_info->{"ldap_server"}.": $?";
$ldap->bind($ldap_info->{"binddn"}, password => $ldap_info->{"bindpw"}) or die "Can't connect to ".$ldap_info->{"ldap_server"}.": $?";
$ldap_cache{"$rcpt_to_domain"} = $ldap; }
my $mesg = $ldap->search ( # perform a search base => $ldap_info->{"basedn"}, scope => "sub", filter => $filter, count => 1, timeout => 5, );
if (! defined $mesg) { die "LDAP connection problem - temporary error - mail requeue"; }
$mesg->code && die "$mesg->error";
(The last line is where I sometimes get a Perl error about an undefined value.)
On a related note, I guess that my LDAP connection could die and so the connection in my %ldap_cache would be wrong. Is there good way to detect if this happens other than just doing a search() and waiting for an error?
For debugging I added this:
if (! defined $mesg) { die "LDAP connection problem - temporary error - mail requeue"; }
use Data::Dumper; my $mesg_dump = Dumper($mesg); `echo "$$ hi" >> /tmp/mesg_dump.txt`; `echo "$$ mesg_dump: $mesg_dump " >> /tmp/mesg_dump.txt`; `echo "$$ bye " >> /tmp/mesg_dump.txt`;
$mesg->code && die "$mesg->error";
I only get:
$$ mesg_dump: ...
If I do an LDAP query for an entry that does not exists. Weird.