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 ofSystemCallError
. As the subclass is created in moduleErrno
, its name will startErrno::
.
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