0

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:

2
  • 1
    The same you know in any language that doesn't have checked exceptions. Or even those that have and throw unchecked. Read the documentation. Read the tests. Read the code. You saw people ask that question multiple times and not get a silver bullet, yet you decided to ask it again. How do you know how to use any API for that matter? Commented Dec 23, 2015 at 20:49
  • How do I find source or tests for ruby-doc.org/core-2.0.0/IO.html#method-i-write I am aware of the "click to toggle source" button, but it doesn't show anything useful. Commented Dec 24, 2015 at 7:17

3 Answers 3

2

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 
Sign up to request clarification or add additional context in comments.

4 Comments

You get -1 for rescuing Exception :)
Well, you don't reraise.
I don't think this is a bad answer. If you're completely not sure then this will at least show you the one that is getting raised so you can deal with accordingly.
I think this is bad process. I don't want to swallow exceptions. What I am currently doing is trying to push code into extreme cases and making program fail, then reading exception name that is thrown. But I am sure I am missing stuff this way and there must be a more efficient way.
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. :)

6 Comments

It's not true that recovering from exception implies knowing what they are. I know how to recover from "you can't write to this folder" or "filename invalid" if I knew what those exceptions were named. And it's not listed anywhere I have looked.
@MarkoAvlijaš: check out this post: blog.nicksieger.com/articles/2006/09/06/…. If you run this code in a rails app, you get much bigger exception tree. There's your list.
Particularly, "no such file" error is called Errno::ENOENT.
Thanks, this is useful. Any idea how to apply this code to a (other people's) class? All I can think of now is run it before you include the class and output results into file, then run it after and do a diff. This way I'll catch unique exceptions, but miss those that standard ruby code is using.
do you want to figure it out and create an answer from it? This question is asked a lot and no real answers are given.
|
-2

The source code is the documentation.

-- Matz

4 Comments

Where to find it? On ruby-doc.org code is useless - it's in C and partial. Take a look at IO#write. ruby-doc.org/core-2.0.0/IO.html#method-i-write
@MarkoAvlijaš Weren't you looking for YAML.load_file?
Yes to load and save settings. For save settings I am using File.write / IO.write
@MarkoAvlijaš: I'm afraid you'll have to read a good chunk of ruby codebase to learn which exceptions are thrown from core and stdlib. This file will provide keywords for grepping (C function names). As an alternative, you can read rubinius code, much less C there :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.