lib/socrates/core/dispatcher.rb in socrates-0.1.18 vs lib/socrates/core/dispatcher.rb in socrates-0.1.19
- old
+ new
@@ -16,10 +16,11 @@
@adapter = adapter
@state_factory = state_factory
@storage = storage || Socrates.config.storage
@logger = Socrates.config.logger
+ @error_handler = Socrates.config.error_handler
@error_message = Socrates.config.error_message || DEFAULT_ERROR_MESSAGE
end
def dispatch(message, context: {})
client_id = @adapter.client_id_from(context: context)
@@ -39,11 +40,11 @@
# Now, we assume the user of this code does this check on their own...
# return false unless conversation_state(user).nil?
# Create state data to match the request.
- state_data = Socrates::Core::StateData.new(state_id: state_id, state_action: :ask)
+ state_data = StateData.new(state_id: state_id, state_action: :ask)
persist_state_data(session.client_id, state_data)
# Send our initial message if one was passed to us.
@adapter.queue_direct_message(session, message, user) if message.present?
@@ -55,19 +56,12 @@
def conversation_state(user)
client_id = @adapter.client_id_from(user: user)
return nil unless @storage.has_key?(client_id)
- begin
- snapshot = @storage.get(client_id)
- state_data = StateData.deserialize(snapshot)
- state_data = nil if state_data.expired? || state_data.finished?
- rescue StandardError => e
- @logger.warn "Error while fetching state_data for client id '#{client_id}'."
- @logger.warn e
- state_data = nil
- end
+ state_data = @storage.fetch(client_id)
+ state_data = nil if state_data&.expired? || state_data&.finished?
state_data
end
private
@@ -117,22 +111,12 @@
@adapter.flush_session(session)
end
# rubocop:disable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
def fetch_state_data(client_id)
- if @storage.has_key?(client_id)
- begin
- snapshot = @storage.get(client_id)
- state_data = StateData.deserialize(snapshot)
- rescue StandardError => e
- @logger.warn "Error while fetching state_data for client id '#{client_id}', resetting state: #{e.message}"
- @logger.warn e
- end
- end
+ state_data = @storage.fetch(client_id) || StateData.new
- state_data ||= StateData.new
-
# If the current state is nil or END_OF_CONVERSATION, set it to the default state, which is typically a state
# that waits for an initial command or input from the user (e.g. help, start, etc).
if state_data.state_id.nil? || state_data.state_id == StateData::END_OF_CONVERSATION
default_state, default_action = @state_factory.default
@@ -150,12 +134,11 @@
state_data
end
# rubocop:enable Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
def persist_state_data(client_id, state_data)
- state_data.reset_elapsed_time
- @storage.put(client_id, state_data.serialize)
+ @storage.persist(client_id, state_data)
end
def instantiate_state(session, state_data)
@state_factory.build(state_data: state_data, adapter: @adapter, session: session)
end
@@ -166,12 +149,15 @@
# Stop transitioning if there's no state to transition to, or the conversation has ended.
state.data.state_id.nil? || state.data.state_id == StateData::END_OF_CONVERSATION
end
- def handle_action_error(e, session, state)
- @logger.warn "Error while processing action #{state.data.state_id}/#{state.data.state_action}: #{e.message}"
- @logger.warn e
+ def handle_action_error(error, session, state)
+ msg = "Error while processing action #{state.data.state_id}/#{state.data.state_action}: #{error.message}"
+ @logger.warn msg
+ @logger.warn error
+
+ @error_handler.call(msg, error) if @error_handler.present?
@adapter.queue_message(session, @error_message, send_now: true)
state.data.clear
state.data.state_id = nil