У меня есть код направляющих, который посылает электронные письма. Следующее находится в моем контроллере:
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
увеличен ТОЛЬКО, когда почта успешно отправляется?
Метод deliver_notification
всегда должен возвращать объект TMail
, независимо от успеха или неудачи. Существует параметр raise_delivery_errors
, который позволит почтовику поднимать исключения при возникновении проблем, но вам придется сохранить их в вашем блоке и увеличивать только при успехе.
Из-за способа доставки почты ActionMailer часто бывает так, что вы не знаете, успешно ли доставлено сообщение или нет. Электронная почта обычно ставится в очередь и доставляется в момент времени, значительно превышающий время вызова метода, и большинство ошибок возникает в этот момент из-за любых трудностей с доставкой. Только адреса электронной почты с диким искажением формы будут отклонены заранее, или если механизм доставки почты не функционирует.
Edit: Added Exception Tracking
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
напрямую, а не отдельные элементы.
Вы можете попросить 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