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