Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/57.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何在ActionMailer中捕获错误异常_Ruby On Rails_Email_Actionmailer - Fatal编程技术网

Ruby on rails 如何在ActionMailer中捕获错误异常

Ruby on rails 如何在ActionMailer中捕获错误异常,ruby-on-rails,email,actionmailer,Ruby On Rails,Email,Actionmailer,问题是,如何通过ActionMailer捕获邮件传递过程中的异常。对我来说,这听起来是不可能的,因为在这种情况下ActionMailer应该向mailserver发送邮件,如果mailserver返回错误,ActionMailer应该向我显示这个错误。我只对计算未送达的邮件感兴趣 你对如何实施这个有什么想法吗? 谢谢 这应该适用于任何环境文件development.rb或production.rb config.action_mailer.raise_delivery_errors = true

问题是,如何通过ActionMailer捕获邮件传递过程中的异常。对我来说,这听起来是不可能的,因为在这种情况下ActionMailer应该向mailserver发送邮件,如果mailserver返回错误,ActionMailer应该向我显示这个错误。我只对计算未送达的邮件感兴趣

你对如何实施这个有什么想法吗?
谢谢

这应该适用于任何环境文件
development.rb
production.rb

config.action_mailer.raise_delivery_errors = true

我在控制器中使用了类似的东西:

 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 "/"

如果您发送了大量电子邮件,您还可以通过执行以下操作使代码更加干燥,并获得电子邮件异常通知:

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
类实用程序
#日志和电子邮件例外
#可选参数:
#请求:用于ExceptionNotifier的请求
#信息:“描述性信息”
def self.log_异常(e,args={})
额外信息=参数[:信息]
Rails.logger.error extra\u info如果是extra\u info
Rails.logger.error e.消息
st=e.backtrace.join(“\n”)
Rails.logger.error st
额外信息| |=“”
请求=参数[:请求]
env=请求?request.env:{}
ExceptionNotifier::Notifier.exception_通知(env,e,:data=>{:message=>“exception:{extra_info}”)。传递
结束
def self.try_delivery_email(选项={},&block)
开始
产量
返回真值
拯救埃奥费罗,
IOError,
时间错误,
Errno::Econreset,
Errno::Econaborted,
埃皮普,
厄尔诺:埃蒂米德奥特,
Net::SMTPAuthenticationError,
Net::SMTPServerBusy,
Net::SMTPSyntaxError,
Net::SMTPUnknownError,
OpenSSL::SSL::SSLError=>e
日志异常(e,选项)
返回错误
结束
结束
结束
从这里得到了我最初的灵感:

class ApplicationMailer

使用rails 5以后的版本。这是最佳实践。

这是受
@sukeerthi adiga

class ApplicationMailer
*是splat操作符。它将数组扩展为参数列表


我不想将异常显示给用户,我只需要标识交付失败。只要您救援并处理异常,用户就不会看到异常!我也喜欢向Airbrake或一些异常通知服务报告情况,这样即使处理得很愉快,我们也能知道是否出现了故障。它不需要是类。只需一个模块,您就可以使用
module\u函数定义方法
,并确保从ApplicationMailer继承其他mailer类
class ApplicationMailer < ActionMailer::Base
  rescue_from [ExceptionThatShouldBeRescued] do |exception|
    #handle it here
  end
end