summaryrefslogtreecommitdiff
path: root/lib/nickserver/handler_chain.rb
blob: f685a2e7cdcfc4a8fcc7897322ab199c06d92033 (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
49
require 'English'

#
# 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
      rescued_exceptions << $ERROR_INFO
      result = false
    end
  end
end