Its good that you check the status of the FTP calls, but if they do fail, you may want to include the specific error message (which many mistakenly believe is in $! but is not). On the Net::FTP->new() call, the error message is in $@, and after you have a valid Net::FTP object (e.g. $ftp), you can call $ftp->message.
Another common mistake is to wrap the $ftp->message in quotes, e.g. $ftp->login('user','passwd') or die "Couldn't login: $ftp->message". If you do that, you'll get a very unhelpful error message :-)