Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.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 &引用;救援例外情况“;未营救超时::net_http中的错误_Ruby_Exception Handling_Rescue - Fatal编程技术网

Ruby &引用;救援例外情况“;未营救超时::net_http中的错误

Ruby &引用;救援例外情况“;未营救超时::net_http中的错误,ruby,exception-handling,rescue,Ruby,Exception Handling,Rescue,我们似乎遇到了这样一种情况,救援异常未捕获特定异常 我正在尝试发送有关发生的任何异常的电子邮件警报,然后继续处理。我们已经对有意退出进行了必要的处理。我们希望循环在警告我们之后继续运行,以防发生任何其他情况 根据堆栈跟踪,未被捕获的异常表面上是Timeout::Error 这是堆栈跟踪,删除了对中间代码的引用(代码的最后一行是request.rb:93): 这是request.rb#send,第93行带有注释: def send build uri = URI.parse(

我们似乎遇到了这样一种情况,
救援异常
未捕获特定异常

我正在尝试发送有关发生的任何异常的电子邮件警报,然后继续处理。我们已经对有意退出进行了必要的处理。我们希望循环在警告我们之后继续运行,以防发生任何其他情况

根据堆栈跟踪,未被捕获的异常表面上是
Timeout::Error

这是堆栈跟踪,删除了对中间代码的引用(代码的最后一行是request.rb:93):

这是request.rb#send,第93行带有注释:

  def send
    build

    uri = URI.parse([DST::Request.configuration[:prefix], @path].join('/'))
    https = Net::HTTP.new(uri.host, uri.port)
    https.use_ssl = true
    https.verify_mode = OpenSSL::SSL::VERIFY_NONE
    https_request = Net::HTTP::Post.new(uri.request_uri.tap{|e| debug_puts "\nURL: #{e}, host:#{uri.host}"})
    # line 93:
    https_request.body = request 
    response = https.request(https_request)
    # the rest should be irrelevant
这里是dst_daemon.rb;第49行用注释表示,应该捕获除故意中断以外的任何内容的
救援异常
接近尾声:

DST::Request.environment = :production
class DST::Request::RequestFailed < Exception; end

Thread.abort_on_exception = true
SEMAPHORE = 'import/dst/start.txt' unless defined?(SEMAPHORE)
DEBUG_DST = 'import/dst/debug.txt' unless defined?(DEBUG_DST)
DEBUG_LOG = 'import/dst/debug.log' unless defined?(DEBUG_LOG)

def debug_dst(*args)
  File.open(DEBUG_LOG, 'a') do |f|
    f.print "#{Time.now.localtime}: "
    f.puts(*args)
  end if debug_dst?
end

def debug_dst?
  File.exist?(DEBUG_DST)
end

dst_ids = [Institution::BAA_DST_WS_CLIENT_ID, Institution::BAA_DST_WS_DEALER_ID]
institutions = Institution.find_all_by_baa_api_financial_institution_id(dst_ids)
DST::Collector.prime_key!

loop do
  begin
    if File.exist?(SEMAPHORE)
      debug_dst 'waking up...'

      custodians = InstitutionAccount.acts_as_baa_custodian.
        find_all_by_institution_id(institutions).select(&:direct?)
      good,bad = custodians.partition do |c|
        c.custodian_users.map{|e2|e2.custodian_passwords.count(:conditions => ['expired is not true']) == 1}.all?
      end
      if bad.present?
        msg = "  skipping: \n"
        bad.each do |c|
          msg += "    #{c.user.full_name_or_email}, custodian id #{c.id}: "
          c.custodian_users.each{|cu| msg += "#{cu.username}:#{cu.custodian_passwords.count(:conditions => ['expired is not true'])}; "}
          msg += "\n"
        end
        AdminSimpleMailer.deliver_generic_mail("DST Daemon skipping #{bad.size} connections", msg)
        debug_dst msg
      end

      Benchmark.measure do
        good.each do |custodian|
          begin
            debug_dst "  collecting for: #{custodian.name}, #{custodian.subtitle}, (#{custodian.id.inspect})"
            # line 49:
            DST::Collector.new(custodian, 0).collect!
          rescue DST::Request::PasswordFailed, DST::Request::RequestFailed  => e
            message = e.message + "\n\n" + e.backtrace.join("\n")
            AdminSimpleMailer.deliver_generic_mail("DST Daemon Connection Failed #{e.class.name}", message)
            debug_dst "  skipping, #{e.class}"
          end
        end
      end.tap{|duration| debug_dst "collection done, duration #{duration.real.to_f/60} minutes. importing" }

      DST::Strategy.new(Date.yesterday, :recompute => true).import!
      debug_dst 'import done.'

      rm SEMAPHORE, :verbose => debug_dst?
    else
      debug_dst 'sleeping.' if Time.now.strftime("%M").to_i % 5 == 0
    end
  rescue SystemExit, Interrupt
    raise
  rescue Exception => e
    message = e.message + "\n\n" + e.backtrace.join("\n")
    AdminSimpleMailer.deliver_generic_mail("DST Daemon Exception #{e.class.name}", message)
  ensure
    sleep 60
  end
end
DST::Request.environment=:生产
类DST::Request::RequestFailed<异常;结束
Thread.abort_on_异常=true
信号量='import/dst/start.txt',除非已定义?(信号量)
DEBUG_DST='import/DST/DEBUG.txt',除非已定义?(DEBUG_DST)
调试日志='import/dst/DEBUG.LOG',除非已定义?(调试日志)
def debug_dst(*args)
打开(调试日志,'a')do | f|
f、 打印“#{Time.now.localtime}:”
f、 puts(*args)
是否在调试时结束?
结束
def调试测试?
文件.exist?(调试测试)
结束
dst_ID=[机构::BAA_dst_WS_客户ID,机构::BAA_dst_WS_经销商ID]
机构=机构。按机构id(dst id)查找所有机构
DST::Collector.prime_键!
环道
开始
如果文件.exist?(信号量)
调试dst“唤醒…”
保管人=机构账户。作为保管人。
按机构id查找所有机构。选择(&:直接?)
好的,坏的=保管人|
c、 保管人用户.map{e2 | e2.保管人密码.count(:conditions=>['expired is not true'])==1}。全部?
结束
如果不好的话,现在呢?
msg=“正在跳过:\n”
不好,每个都可以|
msg+=“#{c.user.全名或电子邮件},保管人id#{c.id}:”
c、 保管人用户。每个{cu124; msg+=“{cu.username}:{cu.保管人密码.count(:conditions=>['expired is not true']))};”
msg+=“\n”
结束
AdminSimpleEmailer.deliver_generic_mail(“DST守护进程跳过#{bad.size}连接”,msg)
调试消息
结束
基准测试
好的,每个人都有监护人|
开始
debug#u dst“为以下对象收集:#{保管人.name},#{保管人.subtitle},(#{保管人.id.inspect})”
#第49行:
DST::Collector.new(保管人,0)。collect!
rescue DST::Request::PasswordFailed,DST::Request::RequestFailed=>e
message=e.message+“\n\n”+e.backtrace.join(“\n”)
AdminSimpleEmailer.deliver_generic_mail(“DST守护程序连接失败#{e.class.name}”,消息)
调试“跳过,{e.class}”
结束
结束
end.tap{| duration | debugdst“收集完成,duration{duration.real.to_f/60}分钟。导入”}
DST::Strategy.new(Date.dayed,:recompute=>true)。导入!
调试dst“导入完成”
rm信号量:verbose=>debugdst?
其他的
调试\u dst'sleeping.'if Time.now.strftime(“%M”).to \u i%5==0
结束
救援系统退出,中断
提升
救援异常=>e
message=e.message+“\n\n”+e.backtrace.join(“\n”)
AdminSimpleEmailer.deliver_generic_mail(“DST守护进程异常#{e.class.name}”,消息)
确保
睡60
结束
结束

除了从SystemExit或Interrupt退出之外,是否不可能使用堆栈跟踪退出此循环?

您可能已经知道,在rescue块内调用
raise
将向调用方引发异常。 由于在ruby 1.8*中,
Timeout::Error
是一个
中断
,因此net_http引发的超时异常将在
rescue SystemExit,INTERRUP
块中处理,而不是在下面的
rescue exception=>e
中处理

要验证
Timeout::Error
是否为中断,只需计算
Timeout::Error.exe
。从中得到的是Timeout::Error继承自的类的层次结构


*ruby1.9中不再是这种情况。

在代码中,实际引发的异常在哪里?堆栈跟踪中没有一行与我看到的任何内容对应。它实际上是在引发一个
Timeout::Error
,它确实继承了
异常
。我根本无法重现此问题。我在代码示例
中添加了一条注释这是引发异常的代码
(尽管我拼写“exception”错误-已修复。我将很快重新发布此问题,现在我发现为了简洁起见,我过度编辑了原始情况。我道歉。我发现异常默认为Class.new(ExitException)…无论如何,当我在控制台中尝试此操作时,exception.class是class,exception.class.parent是object。
class.new(ExitException)
将实际创建一个从
ExitexException
继承的匿名类。当然
异常。类
就是类。这同样适用于
异常。类
,对吗?你真正想要的是
异常。祖先
。这将证明异常是异常的子类。我已经重写了这个问题。我如果有人认为最好删除并重新发布b/c,请告知。顺便说一句,这意味着解决您问题的简单方法是在
救援系统退出之前添加一个显式
救援超时::Error
块,在dst_守护进程中中断一个。rbAwesome,非常感谢您-我没有想到要查看Timeout::错误源自我显式捕获的一个异常。
DST::Request.environment = :production
class DST::Request::RequestFailed < Exception; end

Thread.abort_on_exception = true
SEMAPHORE = 'import/dst/start.txt' unless defined?(SEMAPHORE)
DEBUG_DST = 'import/dst/debug.txt' unless defined?(DEBUG_DST)
DEBUG_LOG = 'import/dst/debug.log' unless defined?(DEBUG_LOG)

def debug_dst(*args)
  File.open(DEBUG_LOG, 'a') do |f|
    f.print "#{Time.now.localtime}: "
    f.puts(*args)
  end if debug_dst?
end

def debug_dst?
  File.exist?(DEBUG_DST)
end

dst_ids = [Institution::BAA_DST_WS_CLIENT_ID, Institution::BAA_DST_WS_DEALER_ID]
institutions = Institution.find_all_by_baa_api_financial_institution_id(dst_ids)
DST::Collector.prime_key!

loop do
  begin
    if File.exist?(SEMAPHORE)
      debug_dst 'waking up...'

      custodians = InstitutionAccount.acts_as_baa_custodian.
        find_all_by_institution_id(institutions).select(&:direct?)
      good,bad = custodians.partition do |c|
        c.custodian_users.map{|e2|e2.custodian_passwords.count(:conditions => ['expired is not true']) == 1}.all?
      end
      if bad.present?
        msg = "  skipping: \n"
        bad.each do |c|
          msg += "    #{c.user.full_name_or_email}, custodian id #{c.id}: "
          c.custodian_users.each{|cu| msg += "#{cu.username}:#{cu.custodian_passwords.count(:conditions => ['expired is not true'])}; "}
          msg += "\n"
        end
        AdminSimpleMailer.deliver_generic_mail("DST Daemon skipping #{bad.size} connections", msg)
        debug_dst msg
      end

      Benchmark.measure do
        good.each do |custodian|
          begin
            debug_dst "  collecting for: #{custodian.name}, #{custodian.subtitle}, (#{custodian.id.inspect})"
            # line 49:
            DST::Collector.new(custodian, 0).collect!
          rescue DST::Request::PasswordFailed, DST::Request::RequestFailed  => e
            message = e.message + "\n\n" + e.backtrace.join("\n")
            AdminSimpleMailer.deliver_generic_mail("DST Daemon Connection Failed #{e.class.name}", message)
            debug_dst "  skipping, #{e.class}"
          end
        end
      end.tap{|duration| debug_dst "collection done, duration #{duration.real.to_f/60} minutes. importing" }

      DST::Strategy.new(Date.yesterday, :recompute => true).import!
      debug_dst 'import done.'

      rm SEMAPHORE, :verbose => debug_dst?
    else
      debug_dst 'sleeping.' if Time.now.strftime("%M").to_i % 5 == 0
    end
  rescue SystemExit, Interrupt
    raise
  rescue Exception => e
    message = e.message + "\n\n" + e.backtrace.join("\n")
    AdminSimpleMailer.deliver_generic_mail("DST Daemon Exception #{e.class.name}", message)
  ensure
    sleep 60
  end
end