【问题标题】:How do I modify the exception message in a rescue clause?如何修改救援子句中的异常消息?
【发布时间】:2014-12-31 08:52:22
【问题描述】:

在下文中,['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= 方法不存在。我该怎么做?

【问题讨论】:

标签: ruby exception


【解决方案1】:

根据@fl00r 回答,但稍微“花哨”:

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)委托给异常对象,因此它保留异常类和回溯。

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 对这个答案的复杂感觉 - 这可能根本不是预期的行为,所有 OP 要求的只是一种从异常中更好地记录消息的方法。您对如何解决此问题的回答可能是正确的,但问题本身可能只是一个示例,因此您并不是针对问题本身。
    【解决方案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
    

    【讨论】:

    • 这里唯一的问题是它也改变了异常的类。
    • @BroiSatse OP 想要原始的异常类吗?
    • @fl004 - 问题中没有说明。然而,由于想要修改异常消息而不是仅仅记录它的修改版本,它会建议 store_exception 方法正在做一些更复杂的异常。使用 ProxyException 也会修改回溯。
    • @BroiSatse 很容易看到e 的类并创建一个execption 或那个类。而且,与消息不同,可以修改回溯;这不是问题。
    猜你喜欢
    • 2012-10-06
    • 2021-10-24
    • 2012-04-15
    • 1970-01-01
    • 2021-12-19
    • 2014-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多