首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何抢救某个命名空间下的所有异常?

如何抢救某个命名空间下的所有异常?
EN

Stack Overflow用户
提问于 2012-07-13 01:59:04
回答 3查看 10.1K关注 0票数 23

有没有办法挽救某个名称空间下的所有异常?

例如,我想拯救所有的Errno::*异常(Errno::ECONNRESET,Errno::ETIMEDOUT)。我可以继续在我的异常行中列出它们,但我想知道我是否可以这样做。

代码语言:javascript
复制
begin
  # my code
rescue Errno
  # handle exception
end

上面的想法似乎不起作用,那么有没有类似的东西可以起作用呢?

EN

回答 3

Stack Overflow用户

发布于 2014-08-12 03:29:55

这是另一个有趣的alternative。可以适应你想要的东西。

粘贴最有趣的部分:

代码语言:javascript
复制
def match_message(regexp)
  lambda{ |error| regexp === error.message }
end

begin
  raise StandardError, "Error message about a socket."
rescue match_message(/socket/) => error
  puts "Error #{error} matches /socket/; ignored."
end

参见ruby 1.8.7解决方案的原始站点。

结果是lambda不接受我最近的ruby版本。似乎选择是使用在1.8.7中起作用的东西,但这是IM较慢(在所有比较中创建一个新类。所以我不推荐使用它,甚至还没有尝试过:

代码语言:javascript
复制
def exceptions_matching(&block)
  Class.new do
    def self.===(other)
      @block.call(other)
    end
  end.tap do |c|
    c.instance_variable_set(:@block, block)
  end
end

begin
  raise "FOOBAR: We're all doomed!"
rescue exceptions_matching { |e| e.message =~ /^FOOBAR/ }
  puts "rescued!"
end

如果有人知道ruby在rescue中删除了对lambda的支持,请发表评论。

票数 4
EN

Stack Overflow用户

发布于 2012-07-13 02:25:48

Errno下的所有类都是SystemCallError的子类。并且SystemCallError的所有子类都是Errno下的类。这两组是相同的,所以只要拯救SystemCallError就可以了。这假设您使用的不是添加到一个库而不是另一个库的外部库。

验证两个集合的身份(使用active_support):

代码语言:javascript
复制
Errno.constants.map {|name|
  Errno.const_get(name)
}.select{|const|
  Class === const
}.uniq.map(&:to_s).sort ==
    SystemCallError.subclasses.map(&:to_s).sort

这将为我返回true

因此,将其应用于您的示例:

代码语言:javascript
复制
begin
  # my code
rescue SystemCallError
  # handle exception
end
票数 3
EN

Stack Overflow用户

发布于 2012-07-13 02:43:58

这里是一个更通用的解决方案,在这种情况下,您想拯救一些Errno类型,而不是其他类型。

创建一个自定义模块,将其包含在我们想要挽救的所有错误类中

代码语言:javascript
复制
module MyErrnoModule; end

根据您的喜好自定义此数组,直到"each“调用。

代码语言:javascript
复制
Errno.constants.map {|name|
  Errno.const_get(name)
}.select{|const|
  Class === const
}.uniq.each {|klass|
  klass.class_eval {
    include MyErrnoModule
  }
}

测试:

代码语言:javascript
复制
begin
  raise Errno::EPERM
rescue MyErrnoModule
  p "rescued #{$!.inspect}"
end

测试结果:

代码语言:javascript
复制
"rescued #<Errno::EPERM: Operation not permitted>"

我猜这比需要检查异常名称的解决方案性能稍好一些。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11457795

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档