Ruby 在使用外部gem时捕获异常

Ruby 在使用外部gem时捕获异常,ruby,twitter,gem,rescue,Ruby,Twitter,Gem,Rescue,我已经编写了一个程序,利用外部ruby gem。由于我正在用它执行许多不同的操作,我希望能够全面地拯救和处理异常,而不是每次调用方法时都实现它 最好的方法是什么? 我是否应该编写自己的方法来简单地调用外部gem并拯救异常?或者是否有其他方法可以执行类似“每当程序中出现此类异常时,以这种方式处理” 我知道,如果我编写外部gem代码,我可以添加这样的错误处理,但这是不可行的 这个问题的基本答案可能是把你正在学习的课程包装起来;Ruby为实现这一点提供了很大的灵活性,因为它缺少方法和非常动态的类环境。

我已经编写了一个程序,利用外部ruby gem。由于我正在用它执行许多不同的操作,我希望能够全面地拯救和处理异常,而不是每次调用方法时都实现它

最好的方法是什么?
我是否应该编写自己的方法来简单地调用外部gem并拯救异常?或者是否有其他方法可以执行类似“每当程序中出现此类异常时,以这种方式处理”


我知道,如果我编写外部gem代码,我可以添加这样的错误处理,但这是不可行的

这个问题的基本答案可能是把你正在学习的课程包装起来;Ruby为实现这一点提供了很大的灵活性,因为它缺少方法和非常动态的类环境。下面是一个例子(可能有致命缺陷,也可能没有致命缺陷,但它展示了以下原则:

# A Foo class that throws a nasty exception somewhere.
class Foo
  class SpecialException < Exception; end

  def bar
    raise SpecialException.new("Barf!")
  end
end

# This will rescue all exceptions and optionally call a callback instead
# of raising.
class RescueAllTheThings
  def initialize(instance, callback=nil)
    @instance = instance
    @callback = callback
  end

  def method_missing(method, *args, &block)
    if @instance.respond_to? method
      begin
        @instance.send(method, *args, &block)
      rescue Exception => e
        @callback.call(e) if @callback
      end
    else
      super
    end
  end
end

# A normal non-wrapped Foo. Exceptions will propagate.
raw_foo = Foo.new

# We'll wrap it here with a rescue so that we don't exit when it raises.
begin
  raw_foo.bar
rescue Foo::SpecialException
  puts "Uncaught exception here! I would've exited without this local rescue!"
end

# Wrap the raw_foo instance with RescueAllTheThings, which will pass through
# all method calls, but will rescue all exceptions and optionally call the
# callback instead. Using lambda{} is a fancy way to create a temporary class
# with a #call method that runs the block of code passed. This code is executed
# in the context *here*, so local variables etc. are usable from wherever the
# lambda is placed.
safe_foo = RescueAllTheThings.new(raw_foo, lambda { |e| puts "Caught an exception: #{e.class}: #{e.message}" })

# No need to rescue anything, it's all handled!
safe_foo.bar

puts "Look ma, I didn't exit!"
#一个在某处抛出严重异常的Foo类。
福班
类SpecialException<异常;结束
def棒
引发SpecialException.new(“Barf!”)
结束
结束
#这将拯救所有异常,并可选地调用回调
#抚养孩子。
把所有的事情都告诉我
def初始化(实例,回调=nil)
@实例=实例
@回调=回调
结束
def方法_缺失(方法、*args和块)
if@instance.response\u to?方法
开始
@send(方法、*args和块)
救援异常=>e
@callback.if@callback调用(e)
结束
其他的
超级的
结束
结束
结束
#正常的非包装Foo。异常将传播。
原始食物=新鲜食物
#我们将在这里用救援包裹它,这样当它升起时我们就不会离开。
开始
生食吧
rescue Foo::SpecialException
在这里写上“意外的例外!如果没有当地的救援,我早就离开了!”
结束
#将raw_foo实例包装为将要通过的所有内容
#所有方法调用,但将援救所有异常并可选地调用
#使用lambda{}是一种创建临时类的奇特方法
#使用运行传递的代码块的#call方法。执行此代码
#在上下文*此处*,因此局部变量等可从
#lambda被放置。
safe|foo=RescueAllTheThings.new(raw|foo,lambda{e|puts“捕获异常:{e.class}:{e.message}”)
#不需要营救任何东西,一切都搞定了!
保险柜
放上“看,妈妈,我没有退出!”
使用一个非常通用的包装器类(如上面的RescueAllTheThings类)是否有意义,或者使用与您试图包装的东西更具体的东西是否有意义,将在很大程度上取决于上下文和您希望解决的特定问题