2010-08-06 66 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