Siju Mohan MM
Siju Mohan MM

Reputation: 143

Handling Exception in Perl

I am new to perl, and I have created a perl script for ftp file transfer.

But if the $ftp->login is unsuccessful, program gets terminated with the following error message:

Uncaught exception from user code:
        Cannot login Login incorrect.
 at ftp.sender.com line 89

Code fragment from the program:

$ftp->login($config->[$i]->{'USERNAME'},$config->[$i]->{'PSWD'}) or die "Cannot login ", $ftp->message;

Is there any way to handle this exception / unsuccessful login, so that program will not terminate?

Upvotes: 0

Views: 722

Answers (1)

simbabque
simbabque

Reputation: 54323

You have several different ways to do stuff only if the login worked.

  • Let the whole program die

    You already know that one. The whole program stops if the login fails. It works because login returns a true value on success, and a false value on failure. So if undef gets returend, the RHS of the or is called, which is die.

    $ftp->login($user, $pw) or die "Cannot login ", $ftp->message;
    
  • Use a do block

    If you want to stick with the or, you can use a do { ... } block to group several statements. This is weird.

    $ftp->login($user, $pw) or do { 
        stuff();
        more_stuff();
    };
    
  • Check the return value of login

    If you put your login in an if, you can call as much code as you want.

    if ( $ftp->login($user, $pw) ) {
         stuff();
         more_stuff();
    }
    
  • Put all of it in a sub and let the login return

    Group all the FTP things into one sub and call that. Then return from the sub if one of the steps fail. To get the error message you could return the ftp object and check the ultimate success outside.

    sub ftp_stuff {
        my ($foo) = @_;
        $ftp->login($user, $pw) or return $ftp;
        $ftp->stuff($foo) or return $ftp;
    
        return $ftp;
    }
    
    # and somewhere else
    my $ftp = ftp_stuff($bar);
    die "Something went wrong: ", $ftp->message if $ftp->message;
    
  • Use die or Exceptions and Try::Tiny

    The nices approach is to use Try::Tiny.

    use Try::Tiny;
    
    try {
        $ftp->login($user, $pw) or die "Cannot login ", $ftp->message;
        stuff() or die "stuff ", $ftp->message;
        # ...
    } catch {
        # exception/error is in $_
        warn "Could not log in" if /Cannot login/;
        # ...
    };
    
    # continue with your program
    

    An alternative to Try::Tiny is an eval block.

    eval {
        $ftp->login($user, $pw) or die "Cannot login ", $ftp->message;
        stuff() or die "stuff ", $ftp->message;
        # ...
    };
    if ($@) {
        # exception/error is in $@
        warn "Could not log in" if $@ =~ /Cannot login/;
        # ...
    };
    

Upvotes: 2

Related Questions