Browse Source

Fixes issue #3381 - Execution timeout while performing request to Zendesk API fails import for current resource.

Thorsten Eckel 4 years ago
parent
commit
cb58c7ed6d

+ 19 - 11
lib/sequencer/unit/import/zendesk/sub_sequence/base.rb

@@ -41,23 +41,31 @@ class Sequencer
             def resource_iteration(&block)
               resource_collection.public_send(resource_iteration_method, &block)
             rescue ZendeskAPI::Error::NetworkError => e
-              status = e.response.status.to_s
+              return if expected_exception?(e)
+              raise if !retry_exception?(e)
+              raise if (fail_count ||= 1) > 10
 
-              if status.match?(/^(4|5)\d\d$/)
+              logger.error e
+              logger.info "Sleeping 10 seconds after ZendeskAPI::Error::NetworkError and retry (##{fail_count}/10)."
+              sleep 10
 
-                # #2262 Zendesk-Import fails for User & Organizations when 403 "access" denied
-                return if status == '403' && resource_klass.in?(%w[UserField OrganizationField])
+              fail_count += 1
+              retry
+            end
 
-                raise if (fail_count ||= 1) > 10
+            # #2262 Zendesk-Import fails for User & Organizations when 403 "access" denied
+            def expected_exception?(e)
+              status = e.response.status.to_s
+              return false if status != '403'
 
-                logger.error e
-                logger.info "Sleeping 10 seconds after ZendeskAPI::Error::NetworkError and retry (##{fail_count}/10)."
-                sleep 10
+              %w[UserField OrganizationField].include?(resource_klass)
+            end
 
-                (fail_count += 1) && retry
-              end
+            def retry_exception?(e)
+              return true if e.message.include?('execution expired')
 
-              raise
+              status = e.response.status.to_s
+              status.match?(/^(4|5)\d\d$/)
             end
 
             def resource_collection

+ 14 - 1
spec/lib/sequencer/unit/import/zendesk/sub_sequence/base_examples.rb

@@ -26,7 +26,8 @@ RSpec.shared_examples 'Sequencer::Unit::Import::Zendesk::SubSequence::Base' do
 
     let(:collection_name) { described_class.name.demodulize.snakecase.to_sym }
     let(:client_collection) { double('ZendeskAPI::Collection') }
-    let(:api_error) { ZendeskAPI::Error::NetworkError.new('Mock err msg', response_obj) }
+    let(:api_error_message) { 'Mock err msg' }
+    let(:api_error) { ZendeskAPI::Error::NetworkError.new(api_error_message, response_obj) }
 
     let(:response_obj) do
       # stubbed methods required for ZendeskAPI::Error::ClientError#to_s
@@ -90,5 +91,17 @@ RSpec.shared_examples 'Sequencer::Unit::Import::Zendesk::SubSequence::Base' do
         end.to raise_error(api_error)
       end
     end
+
+    context 'when execution timeout occurs' do
+      let(:api_error_message) { "execution expired -- get https://example.zendesk.com/api/v2/#{collection_name}" }
+
+      it 'retries ten times, in 10s intervals' do
+        expect do
+          process(params) do |unit|
+            expect(unit).to receive(:sleep).with(10).exactly(10).times
+          end
+        end.to raise_error(api_error)
+      end
+    end
   end
 end