How to catch error exception in ActionMailer

前端 未结 5 776
误落风尘
误落风尘 2020-12-05 00:58

The problem is how can I catch exception in delivering mail by ActionMailer. For me it sounds impossible, because in this case ActionMailer should sent mail to mailserver, a

相关标签:
5条回答
  • 2020-12-05 01:21

    If you are sending a lot of emails, you can also keep your code more DRY and get notifications of exceptions to your email by doing something like this:

    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:

    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
    

    Got my original inspiration from here: http://www.railsonmaui.com/blog/2013/05/08/strategies-for-rails-logging-and-error-handling/

    0 讨论(0)
  • 2020-12-05 01:26

    This is inspired by the answer given by @sukeerthi-adiga

    class ApplicationMailer < ActionMailer::Base
      # Add other exceptions you want rescued in the array below
      ERRORS_TO_RESCUE = [
        Net::SMTPAuthenticationError,
        Net::SMTPServerBusy,
        Net::SMTPSyntaxError,
        Net::SMTPFatalError,
        Net::SMTPUnknownError,
        Errno::ECONNREFUSED
      ]
    
      rescue_from *ERRORS_TO_RESCUE do |exception|
        # Handle it here
        Rails.logger.error("failed to send email")
      end
    
    end
    

    The * is the splat operator. It expands an Array into a list of arguments.

    More explanation about (*) splat operator

    0 讨论(0)
  • 2020-12-05 01:29

    This should work in any of your environment files. development.rb or production.rb

    config.action_mailer.raise_delivery_errors = true
    
    0 讨论(0)
  • 2020-12-05 01:32

    I'm using something like this in the controller:

     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 "/"
    
    0 讨论(0)
  • 2020-12-05 01:38
    class ApplicationMailer < ActionMailer::Base
      rescue_from [ExceptionThatShouldBeRescued] do |exception|
        #handle it here
      end
    end
    

    Works with rails 5 onwards. And it's the best practice.

    0 讨论(0)
提交回复
热议问题