Reputation: 1659
This is actually 3 part question:
I wouldn't ask for no 3 but this question suggests I will encounter wierd issues: Can't rescue YAML.load exception
Based on this question How to know what exceptions to rescue
I got:
Psych::Exception
Psych::BadAlias
Psych::DisallowedClass
Psych::SyntaxError
But when I try to catch that code still fails
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>'
I am looking for ways to catch all of that nonsense. Regardless for the reason of failure, I want to catch it and display a message before it falls back to main exception handling code.
Microsoft, which I don't particularly like, shows all exceptions for every class they ever wrote. Example: https://msdn.microsoft.com/en-us/library/b9skfh7s(v=vs.110).aspx
Upvotes: 1
Views: 556
Reputation: 54243
One way to check would be :
exceptions_before = ObjectSpace.each_object(Class).select{|klass| klass < Exception}
require 'yaml'
exceptions_after = ObjectSpace.each_object(Class).select{|klass| klass < Exception}
It might miss Exceptions that are dynamically generated. Still, here's the difference between the 2, and their ancestors :
(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]
It seems that Psych::Exception
and StringScanner::Error
cover all the exceptions thrown by Psych
.
Anything could go wrong anywhere. Still, the most common exception will be :
Errno::ENOENT
if your .yml
isn't found. You could either rescue the exception or just check that File.exist?
before reading the yaml file.
IMHO, you shouldn't try to rescue every exception.
Even though it looks like you're looking for rescue => e
or even rescue Exception => e
, it's not a good idea.
Upvotes: 2