2014-11-04 32 views
1

在下面,通过['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=不存在。我该怎么做?

回答

0

答案,但稍微更加“花哨”:

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

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 
+0

这里唯一的问题是它也改变了异常的类。 – BroiSatse 2014-11-04 13:12:49

+0

@BroiSatse做的OP想要原始的Exception类吗? – fl00r 2014-11-04 13:15:40

+0

@ fl004 - 这个问题没有说明。然而,由于想要修改异常消息而不是仅仅记录修改后的版本,它会提示store_exception方法在出现异常时更加复杂。使用ProxyException也会修改回溯。 – BroiSatse 2014-11-04 13:24:15

0

一般情况下,你不应该使用的预期情况下的例外(问自己:我的代码工作,如果我删除所有的异常处理代码?)。这是预期的情况下,你可以通过调用紧凑阵列传递给each_with_index之前容易避免:根据@ fl00r答案

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

关于这个答案的复杂感受 - 它可能不是所期望的行为,所有OP要求的是更好地记录异常消息的方式。你的回答在如何解决这个问题上可能是正确的,但问题本身可能只是一个例子,因此你不是针对这个问题本身。 – BroiSatse 2014-11-04 13:08:16