2015-12-28 76 views
-1

•我的工作到Linux服務器遷移到Ubuntu的,從一個10.04更新一到12.04不能調用一個未定義的值的方法「驗證」

•此服務器是負責執行幾個一些Perl模塊通過crontabs。

•這些Perl模塊嚴重依賴30-40 perl擴展。

•我安裝了所有Perl擴展,並且crontabs能夠成功處理,除了由這些PERL擴展的較新版本引起的幾個語法錯誤。

•我需要一些幫助來修改語法以使Perl腳本按預期進行處理。

這是我的錯誤信息:

2015/12/28 12:56:48 ./cms.pl 88 FATAL main - Can't call method "verify" on an undefined value at pm/Emails/Core.pm line 438. 

代碼:

#=================================================================================================== 
# Send an eamil 
# Args: enable_clients?, BCC Arrayref [[email protected], ...], Hashref { email_address, email_subject, email_body } 
#=================================================================================================== 
sub pm::Emails::Core::send_email { 
    my ($self, $enable_clients, $bcc, $email) = @_; 
    # die('Invalid BCC array') unless $bcc; 
    die('Invalid Email hashref') unless ($email && $email->{email_address} && $email->{email_subject} && $email->{email_body}); 

    $email->{email_address} = trim $email->{email_address}; # Trim the email address just to be sure no invalid emails sneak in 

    my $mime = undef; 
    my $smtp = undef; 

    ### 
    # Get a handle to the logger 
    my $logger = Log::Log4perl->get_logger(); 
    die('Failed to create logger') unless $logger; 
    ### 

    ### 
    # Send the email using the local SMTP server 
    # SPAM FILTER NOTES: 
    # We are sending the email as inlined HTML. 
    # Sending the email as a multipart with HTML & PlainText is getting flagged as SPAM. 
    { 
    my $msg = join(', ', 
      (
        'Time:' . localtime(), 
        'Sending Email TO: ' . $email->{email_address}, 
      #'BCC: ' . join(',', @$bcc), 
      'SUBJECT: ' . $email->{email_subject}, 
      'Clients Enabled: ' . ($enable_clients ? 'true' : 'false') 
      ) 
      ); 
    $logger->warn($msg); 
    open(FILE, '>>/var/log/mail.log') or die('Failed to open mail log: /var/log/mail.log'); 
    print FILE $msg . "\n"; 
    close FILE; 
    } 
    ### 

    if (!defined($self->{_phpversion_})) { 
     $self->{_phpversion_} = `php -r 'print phpversion();' 2>/dev/null`; 
    } 

    ### 
    # Generate the MIME email message 
    $mime = MIME::Lite->new( 
       Subject => $email->{email_subject}, 
       To => $email->{email_address}, 
       Type => 'text/html', 
       Data => $email->{email_body}, 
       'Reply-To' => '[email protected]', 
       'Return-Path' => '[email protected]', 
       From => '[email protected]', 
       Organization => 'Testing', 
       'X-Mailer' => 'PHP' . $self->{_phpversion_} 
      ); 


    ### 
    # Check to see if we are sending the email to clients, if not then redirect to another account & update the subject 
    if ($enable_clients) { 
    $logger->warn('Sending email to clients is enabled!'); 
    } else { 
     use Sys::Hostname; 
    $logger->warn('Sending email to clients is disabled!'); 
    $email->{email_address} = '[email protected]'; 
    $email->{email_subject} = '<' . hostname . ' - ADMIN ONLY EMAIL> ' . $email->{email_subject}; 
    $mime->replace(Subject => $email->{email_subject}); 
    } 

    $mime->preamble(''); 
    $mime->top_level(1); 
    $mime = $mime->as_string(); 
    ### 

    ### 
    # Connect to the SMTP server & send the message 
    $logger->debug('Connecting to SMPT server'); 
    $smtp = Net::SMTP->new('localhost', Timeout => 60, Debug => 0, Hello => 'test.com'); 
    $logger->debug('Connected to SMPT server'); 
    ### 

    ### 
    # Verify we can send the email to the included addresses 
    foreach my $email_address (($email->{email_address}), @$bcc) { 
    $logger->debug('Verifying Email address: ' . $email_address); 
    next if $smtp->verify($email_address); 

    $logger->warn('Failed to verify email address: ' . $email_address . ', re-connecting to SMPT'); 
    $smtp = Net::SMTP->new('localhost', Timeout => 60, Debug => 1, Hello => 'test.com'); 
    die('Failed to reconnect to SMPT server') unless $smtp; 
    last; 
    } 
    ### 

    ### 
    # Send the email message 
    $smtp->mail('[email protected]'); 
    $smtp->bcc(@$bcc, { Notify => ['FAILURE','DELAY', 'SUCCESS'] }); 
    $smtp->to($email->{email_address}, { Notify => ['FAILURE','DELAY', 'SUCCESS'] }); 
    $smtp->data; # This will start the data connection for the message body 
    $smtp->datasend($mime); # This will send the data for the message body 
    $smtp->dataend; # This will end the message body and send the message to the user 
    $smtp->quit; 
    ### 

    use List::Util qw[min]; 
    sleep(min(1, int(rand(2)))); 
} 

任何幫助是極大的讚賞。

+1

你似乎在第441行定義了'$ smtp',在你嘗試從它運行'verify'方法後,有3行*。你是否有理由期望它在早期被定義? – tjd

+1

你發佈的代碼片段沒有什麼意義,因爲它通常是用'$ smtp = Net :: SMTP-> new(...);'*之前*嘗試調用其他'$ smtp'上的方法。我猜你留下了一些東西;在代碼中搜索'$ smtp'並找到前幾個事件。 – ThisSuitIsBlackNot

+0

我的歉意傢伙只是發佈完整的代碼,感謝您的反饋。 – virtual020

回答

2

您不會創建$smtp對象(使用$smtp = Net::SMTP->new(...)),直到您嘗試調用其上的verify()方法後的三行。所以當然在那個時候它將會是不確定的。

如果$smtp也是在您之前沒有向我們展示的代碼中創建的,那麼唯一可行的方法是。但假設你已經向我們展示了所有提到的$smtp,那麼這個代碼不可能只在舊服務器上工作。這不是一個更新版本的Perl引起的問題,這是一個永遠不會有效的邏輯錯誤。

解決此問題的顯而易見的方法是重新排序代碼,以便在嘗試使用它之前創建該對象。但是由於我只能看到少量的代碼,我無法知道這是否會在其他地方產生連鎖效應。

您是否考慮過支付Perl程序員來幫助您執行這些遷移?從StackOverflow的期待免費諮詢是不是一個真正的可持續的商業模式: -/

更新:好了,現在你已經添加了更多的代碼,我們可以看到,$smtp是調用初始化前幾行verify。那麼爲什麼你會得到這個錯誤?

如果你讀了documentation for Net::SMTP,在描述new()方法的部分,它說:

如果失敗undef將被退回,並[email protected]將包含 失敗的原因。

看起來這是發生了什麼。但是你的代碼沒有檢查new()的返回代碼,並且假設它總能正常工作 - 這是一個非常奇怪的假設。爲了弄清楚發生了什麼問題,您需要在創建SMTP對象的兩行中添加一些調試輸出。當您有:

$smtp = Net::SMTP->new(...); 

將其更改爲:

$smtp = Net::SMTP->new(...) 
    or die [email protected]; 

這樣一來,如果您無法連接到SMTP服務器,你的程序將與(希望)有用的錯誤信息,這將使死你進一步調查。順便說一句,我不知道你的代碼來自哪裏,但是現在沒人真的推薦Net :: SMTP。這都是相當低級的。你會更好看Email::SenderEmail::Stuffer(這是一種有用的知識,一個Perl程序員能帶給這個項目..

+1

但人們在互聯網上發佈的東西都是免費的!想想他們得到的曝光! – Sobrique

+0

你好戴夫再次感謝迴應這個和我的第二篇文章。我很抱歉沒有發佈完整的代碼,我可以看到有多麼令人沮喪,當一個業餘愛好者尋求幫助,甚至沒有正確提出問題。 :)。你所說的話很有道理,但是由於我只剩下一些錯誤,我想我會放棄這一點。感謝您的反饋意見。非常感謝。 – virtual020

+0

我將運行調試並讓您知道我的結果,這實際上是我遇到的最後一個問題。通過查看您的個人資料,我可以看到您是該領域的專家,感謝您花時間幫助解決此問題。 – virtual020

-1

嘿傢伙只是想跟進這個問題。我嘗試了所有的您的建議和。是無法得到解決

這臺機器上運行的SMTP /郵件的但是更深入的研究表明,它正在運行的Postfix,事實證明這個劇本是爲Sendmail編寫簡單的做了以下內容:

卸載Postfix-

sudo apt-get purge postfix 

安裝Sendmail-

sudo apt-get install sendmail 

全部被解決了,謝謝你們的一切幫助球員。

相關問題