Class: ExceptionCatcher

Inherits:
Object show all
Defined in:
lib/util/exception_catcher.rb

Overview

ExceptionCatcher makes it easy to execute multiple operations even though any might fail with exception

  • executed tasks can be named to make it easier to identify which tasks failed

  • collects result and exceptions for each executed task

  • raises a MultipleExceptions exception if there were more than one exception

    catcher = ExceptionCatcher.new
    catcher.catch(1){raise "1"}
    catcher.catch(2){raise "2"}
    catcher.catch(3){"ok!"}
    catcher.exception(1) # -> exception object raised by the task 1
    catcher.exception(2) # -> exception object raise by the task 2
    catcher.result(3) # -> "ok!"
    catcher.check # raises a MultipleExceptions exception
    

Defined Under Namespace

Classes: MultipleExceptions

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeExceptionCatcher

Returns a new instance of ExceptionCatcher.



36
37
38
39
40
41
# File 'lib/util/exception_catcher.rb', line 36

def initialize
  @mutex = Mutex.new
  @results = {}
  @exceptions = {}
  @tasks = []
end

Instance Attribute Details

#exceptionsObject (readonly)

Returns the value of attribute exceptions.



34
35
36
# File 'lib/util/exception_catcher.rb', line 34

def exceptions
  @exceptions
end

#mutexObject (readonly)

Returns the value of attribute mutex.



34
35
36
# File 'lib/util/exception_catcher.rb', line 34

def mutex
  @mutex
end

#resultsObject (readonly)

Returns the value of attribute results.



34
35
36
# File 'lib/util/exception_catcher.rb', line 34

def results
  @results
end

#tasksObject (readonly)

Returns the value of attribute tasks.



34
35
36
# File 'lib/util/exception_catcher.rb', line 34

def tasks
  @tasks
end

Instance Method Details

#catch(task = nil, &block) ⇒ Object?

Catches exceptions thrown by block

Parameters:

  • task (Object, nil) (defaults to: nil)

    if task is defined, results can be checked per task

  • block, (Proc)

    block which is executed

Returns:

  • (Object, nil)

    returns block’s result or nil if block raised an exception



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/util/exception_catcher.rb', line 47

def catch(task=nil, &block)
  if task.nil?
    task = block
  end
  @mutex.synchronize do
    @tasks << task
  end
  begin
    result = block.call
    @mutex.synchronize do
      @results[task]=result
    end
    result
  rescue Exception => e
    @mutex.synchronize do
      @exceptions[task]=e
    end
    nil
  end
end

#checkObject

Checks if there has been exceptions and raises the original exception if there has been one exception and MultipleExceptions if there has been many exceptions



90
91
92
93
94
95
96
97
98
99
# File 'lib/util/exception_catcher.rb', line 90

def check
  @mutex.synchronize do
    if @exceptions.size == 1
      e = @exceptions.values.first
      raise e.class, e.message, e.backtrace
    elsif @exceptions.size > 1
      raise MultipleExceptions.new("Caught #{@exceptions.size} exceptions!").catcher(self)
    end
  end
end

#exception(task) ⇒ Object?

Returns block’s exception or nil if the block did not raise an exception.

Parameters:

  • task (Object)

    identifies the executed task

Returns:

  • (Object, nil)

    block’s exception or nil if the block did not raise an exception



78
79
80
81
82
# File 'lib/util/exception_catcher.rb', line 78

def exception(task)
  @mutex.synchronize do
    @exceptions[task]
  end
end

#exceptions?bool

Returns exceptions? returns true if there has been exceptions.

Returns:

  • (bool)

    exceptions? returns true if there has been exceptions



85
86
87
# File 'lib/util/exception_catcher.rb', line 85

def exceptions?
  @exceptions.size > 0
end

#result(task) ⇒ Object?

Returns result for the named block or nil if the block ended in exception.

Parameters:

  • task (Object)

    identifies the executed task

Returns:

  • (Object, nil)

    result for the named block or nil if the block ended in exception



70
71
72
73
74
# File 'lib/util/exception_catcher.rb', line 70

def result(task)
  @mutex.synchronize do
    @results[task]
  end
end