2012-01-03 10 views
17

Проблема в том, как я могу поймать исключение при доставке почты ActionMailer. Для меня это кажется невозможным, потому что в этом случае ActionMailer должен отправлять почту почтовому серверу, а если mailserver возвращает ошибку, ActionMailer должен показать мне эту ошибку. Меня интересует только подсчет недостоверных писем.Как уловить ошибку в ActionMailer

У вас есть идеи, как реализовать это? Спасибо!

ответ

23

Я использую что-то вроде этого в контроллере:

if @user.save 
     begin 
     UserMailer.welcome_email(@user).deliver 
     flash[:success] = "#{@user.name} created" 
     rescue Net::SMTPAuthenticationError, Net::SMTPServerBusy, Net::SMTPSyntaxError, Net::SMTPFatalError, Net::SMTPUnknownError => e 
     flash[:success] = "Utente #{@user.name} creato. Problems sending mail" 
     end 
     redirect_to "/" 
11

Это должно работать в любых файлах среды. development.rb или production.rb

config.action_mailer.raise_delivery_errors = true 
+0

Я не хочу, чтобы показать пользователю исключение, мне нужно просто идентифицировать, что доставка не удалось – com

+2

пользователь не будет видеть исключение до тех пор, как вы спасательных и справиться! Мне также нравится сообщать о вещах Airbrake или какой-либо службе уведомлений об исключениях, чтобы мы знали, что происходит в случае сбоев, даже если они обрабатываются приятно. – Ricky

5

Если вы отправляете много писем, вы можете также сохранить ваш код более DRY и получать уведомления исключений на вашу электронную почту, делая что-то вроде этого:

status = Utility.try_delivering_email do 
    ClientMailer.signup_confirmation(@client).deliver 
end 

unless status 
    flash.now[:error] = "Something went wrong when we tried sending you and email :(" 
end 

Utility Класс:

class Utility 
    # Logs and emails exception 
    # Optional args: 
    # request: request Used for the ExceptionNotifier 
    # info: "A descriptive messsage" 
    def self.log_exception(e, args = {}) 
    extra_info = args[:info] 

    Rails.logger.error extra_info if extra_info 
    Rails.logger.error e.message 
    st = e.backtrace.join("\n") 
    Rails.logger.error st 

    extra_info ||= "<NO DETAILS>" 
    request = args[:request] 
    env = request ? request.env : {} 
    ExceptionNotifier::Notifier.exception_notification(env, e, :data => {:message => "Exception: #{extra_info}"}).deliver 
    end 

    def self.try_delivering_email(options = {}, &block) 
    begin 
     yield 
     return true 
    rescue EOFError, 
      IOError, 
      TimeoutError, 
      Errno::ECONNRESET, 
      Errno::ECONNABORTED, 
      Errno::EPIPE, 
      Errno::ETIMEDOUT, 
      Net::SMTPAuthenticationError, 
      Net::SMTPServerBusy, 
      Net::SMTPSyntaxError, 
      Net::SMTPUnknownError, 
      OpenSSL::SSL::SSLError => e 
     log_exception(e, options) 
     return false 
    end 
    end 
end 

Получил мое первоначальное вдохновение здесь: http://www.railsonmaui.com/blog/2013/05/08/strategies-for-rails-logging-and-error-handling/

+0

Это не должен быть класс. Просто модуль, и вы можете определять методы с помощью 'module_function' –