How to rescue all exceptions under a certain namespace? How to rescue all exceptions under a certain namespace? ruby ruby

How to rescue all exceptions under a certain namespace?


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


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 }endbegin  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)  endendbegin  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.


All classes under Errno are subclasses of SystemCallError. And all subclasses of SystemCallError are classes under Errno. The 2 sets are identical, so just rescue SystemCallError. This assumes that you're not using an external lib that adds to one and not the other.

Verify the identity of the 2 sets (using active_support):

Errno.constants.map {|name|  Errno.const_get(name)}.select{|const|  Class === const}.uniq.map(&:to_s).sort ==    SystemCallError.subclasses.map(&:to_s).sort

This returns true for me.

So, applied to your example:

begin  # my coderescue SystemCallError  # handle exceptionend