spoovy
spoovy

Reputation: 343

how rescue ruby exception, but not failure in code block

I want to catch the PuppetError::Error exception so it's not fatal, but a PuppetError::ExecError should be fatal.

My problem seems to be that the rescue clause is catching the PuppetError::Error then elevating it to ExecError status, so it isn't caught by the calling code. I need to limit the rescue clause to one line, the Open3.. line. But how?

module PuppetCert
  def self.remove(instance_hostname)
    begin
      Open3::popen3("puppet cert clean #{instance_hostname}") do |stdin, stdout, stderr, wait_thr|
        if wait_thr.value.success?
          puts "success"
        else
          raise PuppetError::Error
          return
        end
      end
    rescue
      raise PuppetError::ExecError
    end
  end
end

instances.each do |i|
  begin
    PuppetCert.remove(i)
  rescue PuppetError::Error
    logger.error("PuppetCert.remove failed. Not fatal")
  end
end

Thanks in advance

EDIT: To clarify, both PuppetError type are custom types I have created (not shown here) as a way to identify different sorts of failure. PuppetError::Error is for when the system call to the puppet binary fails; PuppetError:ExecError is for when Open3::popen3 fails because it can't find the puppet binary.

Upvotes: 0

Views: 583

Answers (1)

Gerry
Gerry

Reputation: 10507

You could use two rescue clauses, one to catch PuppetError::Error and raise it again, then on the other catch everything else:

module PuppetCert
  def self.remove(instance_hostname)
    begin
      Open3::popen3("puppet cert clean #{instance_hostname}") do |stdin, stdout, stderr, wait_thr|
        if wait_thr.value.success?
          puts "success"
        else
          raise PuppetError::Error
          return
        end
      end
    rescue PuppetError::Error => error
      raise error
    rescue
      raise PuppetError::ExecError
    end
  end
end

The first rescue clause (the order matters, so it must come first) rescues PuppetError::Error and simply raises it again, that is, it only intercepts it before getting to the more general rescue, so it won't get promoted. Every other exception will be rescued by the second rescue clause and promoted as PuppetError::ExecError.

Upvotes: 2

Related Questions