Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to rescue all exceptions under a certain namespace?

Tags:

Is there a way to rescue all exceptions under a certain namespace?

For example, I want to rescue all of the Errno::* exceptions (Errno::ECONNRESET, Errno::ETIMEDOUT). I can go ahead and list them all out on my exception line, but I was wondering if I can do something like.

begin   # my code rescue Errno   # handle exception end 

The above idea doesn't seem to work, thus is there something similar that can work?

like image 234
gylaz Avatar asked Jul 12 '12 17:07

gylaz


People also ask

How do you catch all the exceptions?

Exception handling is used to handle the exceptions. We can use try catch block to protect the code. Catch block is used to catch all types of exception. The keyword “catch” is used to catch exceptions.

How do I rescue two errors in Ruby?

Besides specifying a single exception class to rescue, you can pass an array of exception classes to the rescue keyword. This will allow you to respond to multiple errors in the same way. Multiple rescue blocks can be used to handle different errors in different ways.

How do you handle exceptions in Ruby?

Ruby also provides a separate class for an exception that is known as an Exception class which contains different types of methods. The code in which an exception is raised, is enclosed between the begin/end block, so you can use a rescue clause to handle this type of exception.


2 Answers

All the Errno exceptions subclass SystemCallError:

Module Errno is created dynamically to map these operating system errors to Ruby classes, with each error number generating its own subclass of SystemCallError. As the subclass is created in module Errno, its name will start Errno::.

So you could trap SystemCallError and then do a simple name check:

rescue SystemCallError => e   raise e if(e.class.name.start_with?('Errno::'))   # do your thing... end 
like image 118
mu is too short Avatar answered Sep 30 '22 17:09

mu is too short


Here is another interesting alternative. Can be adapted to what you want.

Pasting most interesting part:

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 

See the original site for ruby 1.8.7 solution.

It turns out lambda not accepted my more recent ruby versions. It seems the option is to use what worked in 1.8.7 but that's IM slower (to create a new class in all comparisons. So I don't recommend using it and have not even tried it:

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 

If somebody knows when ruby removed lambda support in rescue please comment.

like image 34
akostadinov Avatar answered Sep 30 '22 16:09

akostadinov