2015-08-18 60 views
4

我使用的ActionMailer deliver_laterW¯¯ActiveJobs/Sidekiq使用時,捕捉連接和SMTP錯誤:軌道4的ActionMailer - 如何使用deliver_later

config.active_job.queue_adapter = :sidekiq 

,因爲我在開發模式W¯¯MailCatcher測試,唯一的錯誤,我可以美中不足的是errno的:: ECONNREFUSED,設置端口1026,而不是1025

當我測試deliver_now,我得到的變量Errno :: ECONNREFUSED錯誤引發,這是很好的

begin 
    MessageMailer.contact_me_email(@message).deliver_now 
    rescue Errno::ECONNREFUSED, Net::SMTPAuthenticationError, Net::SMTPServerBusy, Net::SMTPSyntaxError, Net::SMTPFatalError, Net::SMTPUnknownError => e 
    flash[:error] = "Problems sending mail. Please try again later" 
    # delete message or resend it ? 
    byebug 
    @message.destroy 
    format.html { render :new } 
    end 

然而,當我要求deliver_later,那麼請求痠痛的sidekiq郵寄隊列,並且不拍攝的錯誤...

 begin 
    MessageMailer.contact_me_email(@message).deliver_later(wait: 1.minute) # in mailers queue 
    rescue Errno::ECONNREFUSED, Net::SMTPAuthenticationError, Net::SMTPServerBusy, Net::SMTPSyntaxError, Net::SMTPFatalError, Net::SMTPUnknownError => e 
    flash[:error] = "Problems sending mail. Please try again later" 
    # delete message or resend it ? 
    byebug 
    @message.destroy 
    format.html { render :new } 
    end 

我如何能捕捉在這種情況下,從SMTP錯誤救援?我想這是一個Sidekiq責任來處理它...任何暗示歡迎..

回答

11

ActiveJobs允許您解救使用rescue_from方法執行作業時發生的錯誤。見the api。你需要在你的ActiveJob子類中實現這個方法。

由於ActionMailer使用DeliveryJobs將消息作爲作業傳遞,因此您需要將rescue_from方法添加到此類以處理異常。

例如,你可以放在config/initializers/action_mailer.rb

ActionMailer::DeliveryJob.rescue_from(StandardError) do |exception| 
    Rails.logger.error "Original record not found: #{@serialized_arguments.join(', ')}" 
end 

這將乾淨拯救任何StandardErrors,並且只需登錄他們,而不是拋出異常。我自己實現這個來安靜Rollbar。

因爲它是一個角落的情況下,這是一個好主意來測試它還有:

spec/initializers/action_mailer_spec.rb

RSpec.describe 'ActionMailer::DeliveryJob error recovery' do 

    it 'should log the deserialization errors' do 
    @user = create(:user) 
    MyCustomMailer.send_something(@user).deliver_later 
    @user.destroy 

    expect(Rails.logger).to receive(:error).at_least(:once) 
    Delayed::Worker.new.work_off 
    end 

end