检测after_action回调中的操作邮件传递失败

Joh*_*gle 8 ruby-on-rails actionmailer delayed-job ruby-on-rails-4

after_action在邮件中使用回调来记录发送的电子邮件.电子邮件通过延迟作业发送.这是有效的,除非我们无法访问远程服务器 - 在这种情况下,电子邮件不会被发送,但我们记录它是.延迟作业稍后重试该电子邮件,并且已成功发送,但我们已记录了已发送的两封电子邮件.

它看起来像这样:

class UserMailer < ActionMailer::Base

  after_action :record_email

  def record_email
   Rails.logger.info("XYZZY: Recording Email")
   @user.emails.create!
  end

  def spam!(user) 
   @user = user
   Rails.logger.info("XYZZY: Sending spam!")
   m = mail(to: user.email, subject: 'SPAM!')
   Rails.logger.info("XYZZY: mail method finished")
   m
  end
end
Run Code Online (Sandbox Code Playgroud)

我这样调用这个代码(使用延迟的可执行邮件程序):

UserMailer.delay.spam!( User.find(1))
Run Code Online (Sandbox Code Playgroud)

当我在调试器中逐步执行此操作时,似乎在传递邮件之前调用了我的after_action方法.

[Job:104580969] XYZZY: Sending spam!
[Job:104580969] XYZZY: mail method finished
[Job:104580969] XYZZY: Recording Email
Job UserMailer.app_registration_welcome (id=104580969) FAILED (3 prior attempts) with Errno::ECONNREFUSED: Connection refused - connect(2) for "localhost" port 1025
Run Code Online (Sandbox Code Playgroud)

如何在我的邮件程序方法中捕获网络错误并记录电子邮件尝试失败,或者什么都不做?我正在使用Rails 4.2.4.

Joh*_*gle 4

这是我想到的,我希望有更好的方法。

我使用了邮件传递回调:

交付回调.rb

class DeliveryCallback
  def delivered_email(mail)
    data = mail.instance_variable_get(:@_callback_data)
    unless data.nil?
      data[:user].email.create!
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

配置/初始化/mail.rb

Mail.register_observer( DeliveryCallback.new )
Run Code Online (Sandbox Code Playgroud)

我替换了我的 record_email 方法:

class UserMailer < ActionMailer::Base

  after_action :record_email

  def record_email
    @_message.instance_variable_set(:@_callback_data, {:user => user}) 
  end
end
Run Code Online (Sandbox Code Playgroud)

这似乎有效,如果远程服务器不可用,则不会调用 returned_email 回调。

有没有更好的办法!?!?