How to know what exceptions to rescue

删除回忆录丶 提交于 2019-12-25 03:47:15

问题


I want a class that will load and save settings in yaml file, and displays an error if something happens. I must catch exceptions and I must know what to catch. There is no guarantee what exception will be raised; user might press CTRL+C or memory may run out, but YAML.load_file can raise only a limited number of exceptions. There is nowhere listed what exceptions a function YAML.load_file might raise.

How can I catch only them when I don't know what those exceptions are?

This question has been asked, but there is no real answer:

  • How to know what exceptions to rescue? Answer is about exceptions in general
  • How to deal with not knowing what exceptions can be raised by a library method in Ruby?
  • Ruby How to know what to rescue?
  • Where to find (or how to read) ruby documentation?
  • Documentation for Ruby exceptions

回答1:


Sometimes you just don't know which kind of exception can be thrown, for that the generic rescue catching exists.

begin
    do_something
rescue KnownException
    treat_exception
# generic exception 
rescue Exception => e
    # you don't know which exception has been raised but all info is in e
    print "Ups I don't know this Exception:#{e.class} error: #{e.message}"
    raise
end



回答2:


How can I catch only them when I don't know what those exceptions are?

What are you going to do when you catch them, I wonder? It makes little sense to catch exceptions for the sake of catching. Swallowing exceptions is especially bad practice.

My rule of thumb is: catch only those I can recover from (this implies already knowing what they are). Let the rest bubble up and crash the program or possibly be catched in one of outer scopes (which will know how to recover from this concrete one).

How to discover currently loaded exception classes

This almost 10 year old code snippet still works today:

exceptions = []
tree = {}
ObjectSpace.each_object(Class) do |cls|
  next unless cls.ancestors.include? Exception
  next if exceptions.include? cls
  exceptions << cls
  cls.ancestors.delete_if {|e| [Object, Kernel].include? e }.reverse.inject(tree) {|memo,cls| memo[cls] ||= {}}
end

indent = 0
tree_printer = Proc.new do |t|
  t.keys.sort { |c1,c2| c1.name <=> c2.name }.each do |k|
    space = (' ' * indent); space ||= ''
    puts space + k.to_s
    indent += 2; tree_printer.call t[k]; indent -= 2
  end
end
tree_printer.call tree

Run it in the rails console and you'll see a lot of exception classes. :)




回答3:


The source code is the documentation.

-- Matz



来源:https://stackoverflow.com/questions/34443407/how-to-know-what-exceptions-to-rescue

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!