summaryrefslogtreecommitdiff
path: root/lib/gitlab/import_export/import_failure_service.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/gitlab/import_export/import_failure_service.rb')
-rw-r--r--lib/gitlab/import_export/import_failure_service.rb51
1 files changed, 51 insertions, 0 deletions
diff --git a/lib/gitlab/import_export/import_failure_service.rb b/lib/gitlab/import_export/import_failure_service.rb
new file mode 100644
index 00000000000..eeaf10870c8
--- /dev/null
+++ b/lib/gitlab/import_export/import_failure_service.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+module Gitlab
+ module ImportExport
+ class ImportFailureService
+ RETRIABLE_EXCEPTIONS = [GRPC::DeadlineExceeded, ActiveRecord::QueryCanceled].freeze
+
+ attr_reader :importable
+
+ def initialize(importable)
+ @importable = importable
+ @association = importable.association(:import_failures)
+ end
+
+ def with_retry(relation_key, relation_index)
+ on_retry = -> (exception, retry_count, *_args) do
+ log_import_failure(relation_key, relation_index, exception, retry_count)
+ end
+
+ Retriable.with_context(:relation_import, on_retry: on_retry) do
+ yield
+ end
+ end
+
+ def log_import_failure(relation_key, relation_index, exception, retry_count = 0)
+ extra = {
+ relation_key: relation_key,
+ relation_index: relation_index,
+ retry_count: retry_count
+ }
+ extra[importable_column_name] = importable.id
+
+ Gitlab::ErrorTracking.track_exception(exception, extra)
+
+ attributes = {
+ exception_class: exception.class.to_s,
+ exception_message: exception.message.truncate(255),
+ correlation_id_value: Labkit::Correlation::CorrelationId.current_or_new_id
+ }.merge(extra)
+
+ ImportFailure.create(attributes)
+ end
+
+ private
+
+ def importable_column_name
+ @importable_column_name ||= @association.reflection.foreign_key.to_sym
+ end
+ end
+ end
+end