Как уловить ошибку в ActionMailer

17

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

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

    
задан com 03.01.2012 в 10:12
источник

3 ответа

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 "/"
    
ответ дан piffy 17.06.2012 в 00:30
источник
11

Это должно работать в любом из ваших файлов окружения. development.rb или production.rb

config.action_mailer.raise_delivery_errors = true
    
ответ дан Sukeerthi Adiga 03.01.2012 в 13:12
источник
  • Я не хочу показывать исключение для пользователя, мне нужна только идентификация, что доставка не удалась –  com 03.01.2012 в 13:22
  • Пользователь не увидит исключение, пока вы его спасаете и обрабатываете! Мне также нравится сообщать о вещах Airbrake или какой-либо службе уведомлений об исключениях, чтобы мы знали, что происходит в случае сбоев, даже если они обрабатываются приятно. –  Mar 21 '14 at 14:35 21.03.2014 в 15:35
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

Класс полезности:

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

Получил свое первоначальное вдохновение отсюда: Ссылка     

ответ дан Michael Yagudaev 13.01.2014 в 07:32
источник
  • Это не обязательно должен быть класс. Просто модуль, и вы можете определять методы с помощью module_function –  Cyril Duchon-Doris 11.04.2016 в 20:31