summaryrefslogtreecommitdiff
path: root/lib/nickserver/handler_chain.rb
blob: afc24a5b57d6c915e5b462d569f77f6cd7b19597 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#
# Handler Chain
#
# A chain of handlers that respond to call. Invoking handle(*args) on the chain
# will call the handlers with the given args until one of them returns a result
# that is truethy (i.e. not false or nil).
#
# You can specify exception classes to rescue with
#   handler_chain.continue_on ErrorClass1, ErrorClass2
# These exceptions will be rescued and tracked. The chain will proceed even if
# one handler raised the given exception. Afterwards you can inspect them with
#   handler_chain.rescued_exceptions
#

module Nickserver
  class HandlerChain

    def initialize(*handlers)
      @handlers = handlers
      @exceptions_to_rescue = []
      @rescued_exceptions = []
    end

    def continue_on(*exceptions)
      self.exceptions_to_rescue += exceptions
    end

    def handle(*args)
      result = nil
      _handled_by = @handlers.find{|h| result = try_handler(h, *args)}
      result
    end

    attr_reader :rescued_exceptions

    protected

    attr_writer :rescued_exceptions
    attr_accessor :exceptions_to_rescue

    def try_handler(handler, *args)
      result = handler.call(*args)
    rescue *exceptions_to_rescue
      self.rescued_exceptions << $!
      result = false
    end
  end
end