diff --git a/app/services/data_imports/intercom/importer.rb b/app/services/data_imports/intercom/importer.rb index 385df025b..feffa8dad 100644 --- a/app/services/data_imports/intercom/importer.rb +++ b/app/services/data_imports/intercom/importer.rb @@ -576,6 +576,10 @@ class DataImports::Intercom::Importer valid_timestamp = value.nil? || value.is_a?(Integer) || value.is_a?(Float) || (value.is_a?(String) && (value.blank? || value.match?(/\A-?\d+(?:\.\d+)?\z/))) raise InvalidMessagePayloadError, "Intercom message #{field} must be a Unix timestamp" unless valid_timestamp + + timestamp_for(value) if value.present? + rescue RangeError + raise InvalidMessagePayloadError, "Intercom message #{field} must be a Unix timestamp" end %w[body subject].each do |field| diff --git a/spec/services/data_imports/intercom/importer_spec.rb b/spec/services/data_imports/intercom/importer_spec.rb index 212d90887..7f1b2cdf0 100644 --- a/spec/services/data_imports/intercom/importer_spec.rb +++ b/spec/services/data_imports/intercom/importer_spec.rb @@ -359,6 +359,32 @@ RSpec.describe DataImports::Intercom::Importer do expect(data_import.stats.dig('errors', 'count')).to eq(1) end + it 'isolates an out-of-range message timestamp while importing valid messages', :aggregate_failures do + malformed_conversation = conversation_payload.deep_dup + malformed_conversation['source']['subject'] = nil + malformed_conversation['source']['body'] = nil + malformed_conversation.dig('conversation_parts', 'conversation_parts').first['created_at'] = Float::INFINITY + allow(client).to receive(:retrieve_conversation).with('conversation_1').and_return(malformed_conversation) + importer = described_class.new(data_import: data_import) + expect(importer).not_to receive(:fallback_message_entries) + + importer.perform + + expect(account.messages.pluck(:source_id)).to eq(['intercom:conversation:conversation_1:part:part_2']) + error = data_import.import_errors.find_by!( + source_object_type: 'message', + source_object_id: 'conversation:conversation_1:part:part_1' + ) + expect(error).to have_attributes( + error_code: described_class::InvalidMessagePayloadError.name, + message: 'Intercom message created_at must be a Unix timestamp' + ) + expect(data_import.import_errors.where(source_object_type: 'message').count).to eq(1) + expect(data_import.reload).to be_completed_with_errors + expect(data_import.stats.dig('messages', 'imported')).to eq(1) + expect(data_import.stats.dig('errors', 'count')).to eq(1) + end + it 'imports historical records without dispatching record events or outbound side effects', :aggregate_failures do dispatched_events = [] allow(Rails.configuration.dispatcher).to receive(:dispatch) do |event_name, *_args|