Error Handling in Net::SSH::Perl

Discussion in 'Perl Misc' started by Keith, Nov 13, 2006.

  1. Keith

    Keith Guest

    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.
     
    Keith, Nov 13, 2006
    #1
    1. Advertising

  2. Keith

    Paul Lalli Guest

    Keith wrote:
    > 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
     
    Paul Lalli, Nov 13, 2006
    #2
    1. Advertising

  3. Keith

    Guest

    Keith wrote:
    > 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


    --
    The best way to get a good answer is to ask a good question.
    David Filmer (http://DavidFilmer.com)
     
    , Nov 13, 2006
    #3
  4. Keith

    Keith Guest

    Awesome -- exactly what I was looking for. Thanks everyone!

    wrote:
    > Keith wrote:
    > > 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
    >
    >
    > --
    > The best way to get a good answer is to ask a good question.
    > David Filmer (http://DavidFilmer.com)
     
    Keith, Nov 13, 2006
    #4
  5. Keith

    J. Gleixner Guest

    On 06/22/12 14:25, dagomakoa wrote:
    > 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. Gleixner, Jun 25, 2012
    #5
  6. Keith

    J. Gleixner Guest

    On 06/28/12 00:41, dagomakoa wrote:
    > 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
     
    J. Gleixner, Jun 28, 2012
    #6
  7. Keith

    Dr.Ruud Guest

    On 2012-06-22 21:25, dagomakoa wrote:

    > 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";


    --
    Ruud
     
    Dr.Ruud, Jul 21, 2012
    #7
  8. "Dr.Ruud" <> writes:
    > On 2012-06-22 21:25, dagomakoa wrote:
    >
    >> 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";
    > };


    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!'
     
    Rainer Weikusat, Jul 22, 2012
    #8
  9. Keith

    Dr.Ruud Guest

    On 2012-07-22 03:31, Ben Morrow wrote:
    > "Dr.Ruud":
    >> dagomakoa:


    >>> 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";
    >> };

    >
    > 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

    --
    Ruud
     
    Dr.Ruud, Jul 22, 2012
    #9
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. loial
    Replies:
    0
    Views:
    406
    loial
    Feb 3, 2009
  2. loial
    Replies:
    0
    Views:
    406
    loial
    Feb 10, 2009
  3. Tench Johnson
    Replies:
    1
    Views:
    297
    Biff Tannen
    Apr 23, 2010
  4. salamond

    net/ssh in ruby. ssh.exec fails

    salamond, Feb 17, 2011, in forum: Ruby
    Replies:
    0
    Views:
    248
    salamond
    Feb 17, 2011
  5. Replies:
    0
    Views:
    107
Loading...

Share This Page