1

我有一个发送电子邮件的 Rails 代码。以下是在我的控制器中:

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       "my_email@example.com"
     subject    sub
     body       :content => recipient, :link => link
   end
end

这一切都很好。我的问题是:

例如,如果在向其中一个人发送邮件时出错,即使这样,我的闪信也会说。Mail was sent to X people

我该怎么做才能确保@index仅在成功发送邮件时才增加?

4

2 回答 2

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"

您使用的示例index++不受 Ruby 支持。你可能想要的是index += 1. 您还@users直接使用数组而不是单个元素。

于 2010-08-06T18:01:32.193 回答
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
于 2010-08-06T18:02:35.377 回答