приращение рельсов без ошибок - PullRequest
1 голос
/ 06 августа 2010

У меня есть код рельсов, который отправляет электронные письма.Следующее в моем контроллере:

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 увеличивался ТОЛЬКО при успешной отправке почты?

Ответы [ 2 ]

1 голос
/ 06 августа 2010

Вы можете попросить 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
1 голос
/ 06 августа 2010

Метод 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 напрямую вместо отдельных элементов.

...