如何修改救援条款中的异常消息?
问题描述:
在下面,通过['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=
不存在。我该怎么做?
答
答案,但稍微更加“花哨”:
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是因为它代表所有的方法完全不可见,包括class
和object_id
到异常对象,因此它保留异常类和回溯。
答
您可以创建自定义的异常,并把它作为一个代理对象
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
答
一般情况下,你不应该使用的预期情况下的例外(问自己:我的代码工作,如果我删除所有的异常处理代码?)。这是预期的情况下,你可以通过调用紧凑阵列传递给each_with_index
之前容易避免:根据@ fl00r答案
['a', nil, 'c'].compact #=> ["a", "c"]
+1
关于这个答案的复杂感受 - 它可能不是所期望的行为,所有OP要求的是更好地记录异常消息的方式。你的回答在如何解决这个问题上可能是正确的,但问题本身可能只是一个例子,因此你不是针对这个问题本身。 – BroiSatse 2014-11-04 13:08:16
这里唯一的问题是它也改变了异常的类。 – BroiSatse 2014-11-04 13:12:49
@BroiSatse做的OP想要原始的Exception类吗? – fl00r 2014-11-04 13:15:40
@ fl004 - 这个问题没有说明。然而,由于想要修改异常消息而不是仅仅记录修改后的版本,它会提示store_exception方法在出现异常时更加复杂。使用ProxyException也会修改回溯。 – BroiSatse 2014-11-04 13:24:15