这实际上是3部分问题:
我不会要求3号,但这个问题表明我会遇到一些奇怪的问题: Can't rescue YAML.load exception
基于这个问题 How to know what exceptions to rescue
我得到了:
Psych::Exception
Psych::BadAlias
Psych::DisallowedClass
Psych::SyntaxError
但是当我试图抓住代码仍然失败时
irb(main):002:0> begin
irb(main):003:1* YAML.load_file('test_file_does_not_exist')
irb(main):004:1> rescue Psych::Exception
irb(main):005:1> puts $!.message
irb(main):006:1> end
Errno::ENOENT: No such file or directory @ rb_sysopen - test
from /home/marko/.gem/ruby/2.3.1/gems/psych-2.1.0/lib/psych.rb:474:in `initialize'
from /home/marko/.gem/ruby/2.3.1/gems/psych-2.1.0/lib/psych.rb:474:in `open'
from /home/marko/.gem/ruby/2.3.1/gems/psych-2.1.0/lib/psych.rb:474:in `load_file'
from (irb):3
from /home/marko/.rubies/ruby-2.3.1/bin/irb:11:in `<main>'
我正在寻找方法来捕捉所有这些废话。无论失败的原因是什么,我都想抓住它并在它回到主要的异常处理代码之前显示一条消息。
微软,我不是特别喜欢,它显示了他们写过的每个课程的所有例外情况。例: https://msdn.microsoft.com/en-us/library/b9skfh7s(v=vs.110).aspx
答案 0 :(得分:2)
检查的一种方法是:
exceptions_before = ObjectSpace.each_object(Class).select{|klass| klass < Exception}
require 'yaml'
exceptions_after = ObjectSpace.each_object(Class).select{|klass| klass < Exception}
它可能会错过动态生成的异常。不过,这是2和他们的祖先之间的区别:
(exceptions_after - exceptions_before).each do |yaml_exception|
p yaml_exception.ancestors
end
# [Psych::SyntaxError, Psych::Exception, RuntimeError, StandardError, Exception, Object, Kernel, BasicObject]
# [Psych::DisallowedClass, Psych::Exception, RuntimeError, StandardError, Exception, Object, Kernel, BasicObject]
# [Psych::BadAlias, Psych::Exception, RuntimeError, StandardError, Exception, Object, Kernel, BasicObject]
# [Psych::Exception, RuntimeError, StandardError, Exception, Object, Kernel, BasicObject]
# [StringScanner::Error, StandardError, Exception, Object, Kernel, BasicObject]
似乎Psych::Exception
和StringScanner::Error
涵盖Psych
引发的所有例外情况。
任何地方都可能出错。不过,最常见的例外是:
Errno::ENOENT
如果找不到您的.yml
。您可以抢救异常,也可以在阅读yaml文件之前检查File.exist?
。
即使看起来你正在寻找rescue => e
甚至是rescue Exception => e
,它仍然是not a good idea。