2010-08-06 46 views
1

我有一個發送電子郵件的軌道代碼。以下是在我的控制器:沒有錯誤的軌道增量

def create 
    @users = Users.find(:all) 
    @sub = params[:sub] 
    @body = params[:body] 
    @index = 0 
    @users.each {|i| index++; Notifier.deliver_notification(@users.email_address, @sub, @body, @users.unsubscribe_link);} 
    flash[:notice] = "Mail was sent to " + @index + " people" 
end 

我已經在我的模型

class Notifier < ActionMailer::Base 
    def notification(email, sub, content, link) 
    recipients email 
    from  "[email protected]" 
    subject sub 
    body  :content => recipient, :link => link 
    end 
end 

這一切工作正常以下。我的問題是:

例如,如果在向其中一個人發送郵件時發生錯誤,即使那時我的Flash消息也會說。 Mail was sent to X people

如何才能確保@index只有在郵件成功發送時纔會增加?

回答

1

deliver_notification方法應始終返回一個TMail對象,無論成功或失敗。有一個raise_delivery_errors設置,如果遇到問題,郵件程序可以提示異常,但是您必須在塊中解救這些異常,並且只有在成功時纔會增加。

由於郵件是由ActionMailer提供的,通常情況下你不知道郵件是否成功。電子郵件通常會排隊等待並在遠遠超出方法調用的時間點發送,而且由於交付中遇到任何困難,此時大多數錯誤都會發生。這只是非常畸形的電子郵件地址,將被拒絕,或者如果郵件傳遞機制不起作用。

編輯:添加例外跟蹤

count = 0 
@users.each do |user| 
    begin 
    Notifier.deliver_notification(
     user.email_address, 
     @sub, 
     @body, 
     user.unsubscribe_link 
    ) 

    count += 1 
    rescue => e 
    # Something went wrong, should probably store these and examine them, or 
    # at the very least use Rails.logger 
    end 
end 

flash[:notice] = "Mail was sent to #{count} people" 

您的示例使用不被支持的Ruby index++。你可能想要的是index += 1。您還直接使用@users陣列而不是單個元素。

+0

謝謝。我明白那個。只有我試圖捕獲的錯誤是如果電子郵件地址不存在或者電子郵件地址錯誤。在這些情況下,我注意到錯誤是馬上扔掉的。 (至少在本地主機上) – 2010-08-06 19:27:32

+0

沒有可靠的方法來測試電子郵件地址是否存在。許多服務器實施悄悄地接受和丟棄無效的電子郵件,以防止垃圾郵件發送者進行字典探測有效的電子郵件地址。另外,由於您可能會將您的電子郵件發送給某種中介,因此您希望的最好方法是驗證接收方的主機名或域是否有有效的MX。如果您想驗證電子郵件地址,請根據[RFC822正則表達式](http://tfletcher.com/lib/rfc822.rb)進行檢查。請參閱我的修改後的答案,瞭解如何更改計數。 – tadman 2010-08-08 18:46:42

1

您可以要求ActionMailer爲您拋出異常,然後只計算那些不會導致異常的交付。

ActionMailer::Base.raise_delivery_errors = true 
@users.each do |i| 
    begin 
    Notifier.deliver_notification(@users.email_address, @sub, @body, @users.unsubscribe_link) 
    index++ 
    rescue Exception => e 
    # Do whatever you want with the failed deliveries here 
    end 
end