访问引发异常的接收对象

时间:2017-07-17 20:28:20

标签: ruby exception

在调试ActionMailer的一个非常奇怪的问题时,我意识到我不知道如何访问创建异常的对象。不是例外,而是对象本身。

begin
  AppMailer.send_invoice(hostel_resident).deliver_later
  flash[:success] = "Your invoice was sent successfully!"
rescue => msg 
  # display the system generated error message  
  flash[:error] = "#{msg}" 
end  

NoMethodError: undefined method `disposition_type' for #<Mail::UnstructuredField:0x009g71c2a68258>

此代码非常适合捕获任何异常并打印消息。

但是,如何获得<Mail::UnstructuredField:0x009g71c2a68258>对象?我希望能够和这个人玩游戏,阅读里面的消息,并且通常只能访问它。

这必须是可行的,但inspect没有帮助,cause没有用,backtrace只是告诉你发生了什么。我需要那个对象,即不存在的方法的接收者。

谢谢!

动作制作者(4.2.4) 邮件(2.6.3)

2 个答案:

答案 0 :(得分:0)

这似乎有效,使用NameError上的receiverNoMethodError是其子女)

obj = Object.new
puts obj.to_s

begin
  obj.do_something
rescue NoMethodError => e
  puts e.message
  puts e.receiver
end

# #<Object:0x007fa5ac84da88>
# undefined method `do_something' for #<Object:0x007fa5ac84da88>
# #<Object:0x007fa5ac84da88>

这似乎需要ruby&gt; = 2.3,为&lt;执行此操作2.3,AFAIK你必须做这样的事情(没有在旧红宝石中测试,但应该工作):

class MyNoMethodError < NoMethodError
  attr_accessor :my_receiver
end

obj = Object.new
puts obj.to_s

begin
  begin
    obj.do_something
  rescue NoMethodError => e
    # rescue the exception and wrap it in the method that caused it, using `self` instead of `obj`
    error = MyNoMethodError.new(e)
    error.my_receiver = obj
    raise error
  end
rescue MyNoMethodError => c
  puts c.inspect        # custom exception stuff
  puts c.cause.inspect  # original exception stuff
  puts c.my_receiver
end

# #<Object:0x007f884e846d58>
# #<MyNoMethodError: undefined method `do_something' for #<Object:0x007f884e846d58>>
# #<NoMethodError: undefined method `do_something' for #<Object:0x007f884e846d58>>
# #<Object:0x007f884e846d58>

答案 1 :(得分:0)

好像您正在使用mail gem。这是已知的问题,已在GitHub中报告。请参阅#851

尝试使用不同版本的gem,2.6系列。