如何在rescue子句中修改异常消息?

时间:2014-11-04 12:50:27

标签: ruby exception

在下文中,['a', nil, 'c']上的nil上的迭代将失败,因为您无法执行nil + 'd'。我想拯救该消息,修改它,并将其传递给另一个存储错误的方法。

number = 0
begin
  ['a', nil, 'c'].each_with_index do |entry, i|
    entry + 'd'
    number = i
  end
rescue => e
  e.message="#{e.message} (happened at entry: #{number})"
  store_exception(e)
end

问题是,方法message=不存在。我该怎么做?

3 个答案:

答案 0 :(得分:3)

您可以创建自定义异常并将其用作代理对象

class ProxyException < StandardError; end

number = 0
begin
  ['a', nil, 'c'].each_with_index do |entry, i|
    entry + 'd'
    number = i
  end
rescue => e
  e = ProxyException.new "#{e.message} (happened at entry: #{number})"
  store_exception(e)
end

答案 1 :(得分:0)

通常,您不应该对EXPECTED情况使用异常(问问自己:如果我删除所有异常处理代码,我的代码是否会起作用?)。这是一个预期的情况,您可以通过在将数组传递给each_with_index之前调用compact来轻松避免:

['a', nil, 'c'].compact #=> ["a", "c"]

答案 2 :(得分:0)

根据@ fl00r答案回答,但稍微多一点&#39; fancy&#39;:

class ProxyException < BasicObject
  def initialize(exception, message=nil)
    @exception, @message = exception, message
  end

  def message
    @message || @exception.message
  end

  def method_missing(method_name, *args, &block)
    @exception.public_send(method_name, *args, &block)
  end
end

然后简单地说:

number = 0
begin
  ['a', nil, 'c'].each_with_index do |entry, i|
    entry + 'd'
    number = i
  end
rescue => e
  e = ProxyException.new e, "#{e.message} (happened at entry: #{number})"
  store_exception(e)
end

ProxyException完全不可见,因为它将所有方法(包括classobject_id)委托给异常对象,因此它保留了异常类和回溯。