Error Handling in Net::SSH::Perl

K

Keith

Hi, I'm a bit naive with both Perl and SSH, but I'm trying to write a
script that checks a bunch of Cisco devices to verify that it can log
into them via SSH. I installed Net::SSH::perl, and it is working well.

However, the source code of Net::SSH::perl makes several calls to die()
or croak() when it has any problems connecting such as not being able
to reach the host, bad password, etc. Some of the functions that do
this are _connect and _setup_connection. I don't want the program to
die when these things happen though; I just want my script to know that
it was unsuccessful (so it can log this into a database, for example)
and continue to run.

I've written my own versions of _connect and _setup_connection to
handle this; I just have the functions return -1 instead of croaking,
but my code is getting really ugly. Does anyone have any suggestions
on how to handle this? I'd appreciate the help.
 
P

Paul Lalli

Keith said:
Hi, I'm a bit naive with both Perl and SSH, but I'm trying to write a
script that checks a bunch of Cisco devices to verify that it can log
into them via SSH. I installed Net::SSH::perl, and it is working well.

However, the source code of Net::SSH::perl makes several calls to die()
or croak() when it has any problems connecting such as not being able
to reach the host, bad password, etc. Some of the functions that do
this are _connect and _setup_connection. I don't want the program to
die when these things happen though; I just want my script to know that
it was unsuccessful (so it can log this into a database, for example)
and continue to run.

I've written my own versions of _connect and _setup_connection to
handle this; I just have the functions return -1 instead of croaking,
but my code is getting really ugly. Does anyone have any suggestions
on how to handle this? I'd appreciate the help.

Exception handling in Perl is most basically handled by eval(). Just
wrap your call to functions that may day in an eval{} block. If the
functions called die() or croak(), your program will continue like
normal, but $@ will be set to the error message that would have been
printed to STDERR.

my $ssh;
eval {
$ssh = Net::SSH::perl->connect( ... );
};
if ($@) {
warn "Connect failed: $@\n";
}

Paul Lalli
 
U

usenet

Keith said:
I don't want the program to
die when these things happen though; I just want my script to know that
it was unsuccessful (so it can log this into a database, for example)
and continue to run.

Then wrap your call in an eval

perldoc -f eval
 
J

J. Gleixner

my $ssh;
eval {
$ssh = Net::SSH::perl->connect( ... );
};
if ($@) {
warn "Connect failed: $@\n";
}

It does not work with me, should we remove the option -w on the shebang or remove use warnings / use strict?

You generally don't call 'connect' when using Net::SSH::perl.

When you instantiate the class, using new(), it will 'connect' or 'die'
if the socket connection fails.

use Net::SSH::perl;
eval {
my $ssh = Net::SSH::perl->new(... );
$ssh->login( ... );
my ( $o, $e, $ev ) = $ssh->cmd( ... );
};

die "SSH Failed: $@" if $@;


perldoc Net::SSH::perl
 
J

J. Gleixner

You generally don't call 'connect' when using Net::SSH::perl.

When you instantiate the class, using new(), it will 'connect' or 'die'
if the socket connection fails.

yeah ! That's right

Please learn how to quote.
Ben> My problem is that I do express a wrong password but I do not get desired error message

use Net::SSH::perl;
eval {
my $ssh = Net::SSH::perl->new("$host");
$ssh->login("$user", "$pass");

};

my $error = "SSH Failed: $@" if $@;

It seems that eval does me sending anything actually $@ is NULL

'eval' works fine and the above code is fine. Look at the source
for the login method, it's a setter, it doesn't actually do
anything other than set the username and password it will use
when sending the command, so it's not going to 'die'.

When you actually attempt to run something:

$ssh->cmd(...);

is where it might die. cmd() returns the output, error
mesage, and the exit status, which makes it pretty easy
to use.

Take a look at the documentation before going any further:

perldoc Net::SSH::perl
 
D

Dr.Ruud

my $ssh;
eval {
$ssh = Net::SSH::perl->connect( ... );
};
if ($@) {
warn "Connect failed: $@\n";
}

It does not work with me, should we remove the option -w on the shebang or remove use warnings / use strict?

Don't base code flow on $@.
Write it like this:

my $ssh;
eval {
$ssh= Net::SSH::perl->connect( ... );
1; # success
}
or do {
my $eval_error = $@ || 'Zombie Error';
warn "Connect failed: ", $eval_error, "\n";
};


or compacter:

my $ssh;
eval { $ssh= Net::SSH::perl->connect( ... ); 1 }
or warn "Connect failed: ", ( $@ || 'Zombie Error' ), "\n";
 
R

Rainer Weikusat

Dr.Ruud said:
Don't base code flow on $@.
Write it like this:

my $ssh;
eval {
$ssh= Net::SSH::perl->connect( ... );
1; # success
}
or do {
my $eval_error = $@ || 'Zombie Error';
warn "Connect failed: ", $eval_error, "\n";
};

This should still be: Don't use exceptions. That's just .... wrong!
The problem with this is, not everyone whose code you might need to
use at some point in time cares for these semi-religious convictions.
Eg, the mod_perl error handling is exception based. Since $@ can also
contain a reference to some object, there might even be some kind of
structured error handling based on some hierarchy of exception
classes. Even real error handling, such as automatically reconnecting
to some database server and re-executing queued statements, possibly,
after re-preparing them, in case the error was not caused by a
statement not just "****! It didn't work!!" error handling aka 'Zombie
error! It returned zero and I don't know why!'
 
D

Dr.Ruud

"Dr.Ruud":

use Try::Tiny;

my $ssh =
try { Net::SSH::perl->connect(...) }
catch {
warn "Connect failed: $_\n";
undef;
};

The final 'undef' is the value assigned to $ssh if the connection fails.

Try::Tiny is certainly fine for many situations.
http://www.perladvent.org/2011/2011-12-17.html
So use it if you can.


It presents itself as "bare bones" but it can't be,
mainly because of the minimal exception support in Perl.
So it needs to bring its own set of rules and exceptions and overhead.

At least check its Caveats section
http://search.cpan.org/perldoc?Try::Tiny
Also see: http://wonkden.net/dcbpw_ttch.html
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,073
Latest member
DarinCeden

Latest Threads

Top