Module: RemotelyExceptional::Handlers::PrioritizedHandler::ClassMethods

Defined in:
lib/remotely_exceptional/handlers/prioritized_handler.rb

Instance Method Summary collapse

Instance Method Details

#===(exception) ⇒ Boolean

Determines if any of the available handlers match the provided exception.

Parameters:

  • exception (Exception)

    An exception.

Returns:

  • (Boolean)

    Returns true if a handler is available that matches the given exception. Returns false if none of the available handlers match the given exception.



20
21
22
# File 'lib/remotely_exceptional/handlers/prioritized_handler.rb', line 20

def ===(exception)
  !!handler_for_exception(exception)
end

#block_handlersHash{Integer,Set}

Returns the Hash of block handlers by priority.

Returns:

  • (Hash{Integer,Set})

    The Hash of priorities and which block handlers belong to those priorities.



28
29
30
# File 'lib/remotely_exceptional/handlers/prioritized_handler.rb', line 28

def block_handlers
  Thread.current["#{name}.block_handlers"] ||= Hash.new(&HASH_BUILDER)
end

#default_priorityInteger

The default priority level that should be used for handlers when no priority is provided.

Returns:

  • (Integer)

    The default priority level.



36
37
38
# File 'lib/remotely_exceptional/handlers/prioritized_handler.rb', line 36

def default_priority
  const_get(:DEFAULT_PRIORITY)
end

#handle(exception = $!, context = {}) ⇒ Symbol

Finds the handler with the highest priority that matches the exception and uses this handler to handle the exception. If no handlers are available that match the given exception, the exception is re-raised.

Parameters:

  • exception (Exception) (defaults to: $!)

    The exception to handle.

  • context (Hash{Symbol=>Object}) (defaults to: {})

    An optional Hash of additional contextual information about the exception.

Returns:

  • (Symbol)

    Returns a symbol indicating what action should be taken to continue execution. Depending on the situation, valid values include:

    :continue, :raise, :retry

Raises:

  • (exception)

    The given exception is reraised if no handler is found that matches the given exception.



52
53
54
55
56
57
# File 'lib/remotely_exceptional/handlers/prioritized_handler.rb', line 52

def handle(exception = $!, context = {})
  context, exception = exception, $! if exception.is_a?(Hash)
  priority_handler = handler_for_exception(exception)
  raise exception if !priority_handler
  priority_handler.handle(exception, context)
end

#handler_for_exception(exception) ⇒ RemotelyExceptional::Handler?

Finds the handler with the highest priority that matches the given exception. Returns nil if no matching handler can be found.

Parameters:

  • exception (Exception)

    The exception to find a matching handler for.

Returns:

  • (RemotelyExceptional::Handler)

    Returns the handler with the highest priority that matches the given exception. If no handler is found, returns nil.

  • (nil)

    Returns nil if no matching handler could be found.



67
68
69
# File 'lib/remotely_exceptional/handlers/prioritized_handler.rb', line 67

def handler_for_exception(exception)
  prioritized_handlers.detect { |handler| handler === exception }
end

#prioritized_handlersEnumerator<RemotelyExceptional::Handler>

Returns an enumerator that yields block handlers and registered handlers in priority ASC, name ASC order. The collection is lazily generated, so changes to the sets of handlers may appear during traversal. If consistent state is necessary, force the returned enumerator to eagerly generate the full collection using #to_a or similar.

Returns:

  • (Enumerator<RemotelyExceptional::Handler>)

    An enumerator of all known block handlers and registered handlers in priority ASC, name ASC order.



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/remotely_exceptional/handlers/prioritized_handler.rb', line 80

def prioritized_handlers
  Enumerator.new do |yielder|
    priorities = (registered_handlers.keys | block_handlers.keys).sort!
    priorities.uniq!
    priorities.each do |priority|
      if registered_handlers.key?(priority)
        collected_handlers = registered_handlers[priority].to_a
      end
      if block_handlers.key?(priority)
        temp_handlers = block_handlers[priority].to_a
        collected_handlers &&= collected_handlers.concat(temp_handlers)
        collected_handlers ||= temp_handlers
      end
      collected_handlers.sort_by!(&:name)
      collected_handlers.uniq!
      collected_handlers.each { |handler| yielder << handler }
    end
  end
end

#register_handler(handler, options = {}) ⇒ Boolean

Adds the given handler to the set of registered handlers. Optionally, a priority may be supplied. If no priority is supplied the default priority is used.

Parameters:

  • handler (RemotelyExceptional::Handler)

    The handler that should be registered.

  • options (Hash{Symbol=>Object}) (defaults to: {})

    A Hash of optional arguments.

Options Hash (options):

  • :priority (Integer) — default: {::default_priority}

    The priority of the handler.

Returns:

  • (Boolean)

    Returns true if the handler was successfully registered for the given priority. Returns false if the handler was already registered for the given priority.



112
113
114
115
# File 'lib/remotely_exceptional/handlers/prioritized_handler.rb', line 112

def register_handler(handler, options = {})
  priority = options[:priority] || default_priority
  !!registered_handlers[priority].add?(handler)
end

#registered_handlersHash{Integer,Set<RemotelyExceptional::Handler>}

Returns the Hash of registered handlers by priority.

Returns:



121
122
123
# File 'lib/remotely_exceptional/handlers/prioritized_handler.rb', line 121

def registered_handlers
  Thread.current["#{name}.registered_handlers"] ||= Hash.new(&HASH_BUILDER)
end

#remove_handler(handler, options = {}) ⇒ Boolean

Removes the given handler. By default removes the handler from the default_priority, but a :priority option may be supplied to remove the handler from a specified priority.

Parameters:

  • handler (RemotelyExceptional::Handler)

    The handler that should be removed.

  • options (Hash{Symbol=>Object}) (defaults to: {})

    A Hash of optional arguments.

Options Hash (options):

  • :priority (Integer) — default: {::default_priority}

    The priority that should be searched for the given handler.

Returns:

  • (Boolean)

    Returns true if the handler was successfully removed for the given priority. Returns false if the handler was not registered for the given priority.



137
138
139
140
141
# File 'lib/remotely_exceptional/handlers/prioritized_handler.rb', line 137

def remove_handler(handler, options = {})
  priority = options[:priority] || default_priority
  registered_handlers.key?(priority) &&
    !!registered_handlers[priority].delete(handler)
end

#reset_handlers!true

Clears all block handlers and registered handlers.

Returns:

  • (true)


147
148
149
150
151
# File 'lib/remotely_exceptional/handlers/prioritized_handler.rb', line 147

def reset_handlers!
  Thread.current["#{name}.registered_handlers"] = nil
  Thread.current["#{name}.block_handlers"] = nil
  true
end

#with_handler(handler, options = {}) ⇒ Boolean

Registers a handler for the duration of the given block. By default registers the block at the default priority, but a specific priority may be supplied as an option.

Parameters:

  • handler (RemotelyExceptional::Handler)

    The handler that should be registered.

  • options (Hash{Symbol=>Object}) (defaults to: {})

    A Hash of optional arguments.

Options Hash (options):

  • :priority (Integer) — default: {::default_priority}

    The priority that should be used to register the handler.

Returns:

  • (Boolean)

    Returns true if the block handler was successfully registered for the given priority. Returns false if a matching block handler was already registered for the given priority.

Raises:

  • (ArgumentError)

    if a block is not provided.



166
167
168
169
170
171
172
173
174
175
176
# File 'lib/remotely_exceptional/handlers/prioritized_handler.rb', line 166

def with_handler(handler, options = {})
  raise ArgumentError, "Block required!" unless block_given?

  priority = options[:priority] || default_priority
  if block_handlers[priority].add?(handler)
    added_handler = true
  end
  yield
ensure
  block_handlers[priority].delete(handler) if added_handler
end