Persist reassignment error to source users on failure
What does this MR do and why?
Previously, when a source user failed reassignment, the failure's exception message was logged to importer.log but not persisted to the reassignment_error column on the source user record, even though the column exists and is already on ImportSourceUser GraphQL objects. This MR updates Import::ReassignPlaceholderUserRecordsWorker to truncate and save the failure exception so that it can be returned when querying for source users in the API. This change will support implementing retrying failed placeholder reassignments.
References
- Placeholder user mapping docs: https://docs.gitlab.com/user/import/mapping/#bypass-confirmation-when-reassigning-placeholder-users
- Related to Unable to retry or recover from FAILED status d... (#589777)
Screenshots or screen recordings
The UI was technically already displaying the error message on the placeholder user table, but it was never visible because we never persisted it:
How to set up and validate locally
- Find or create an import source user (placeholder user) by running an import from any of the supported importers. Do not import a project into a personal namespace because it will assign all contributions directly to the personal namespace's user.
- Once the import finishes, update
Import::ReassignPlaceholderUserRecordsWorkerto raise an error. Otherwise, you're unlikely to get the reassignment to fail. Something like:
diff --git a/app/workers/import/reassign_placeholder_user_records_worker.rb b/app/workers/import/reassign_placeholder_user_records_worker.rb
index 0004fbc1c95e24..f6e64c64861b32 100644
--- a/app/workers/import/reassign_placeholder_user_records_worker.rb
+++ b/app/workers/import/reassign_placeholder_user_records_worker.rb
@@ -11,7 +11,7 @@ class ReassignPlaceholderUserRecordsWorker
data_consistency :sticky
feature_category :importers
deduplicate :until_executed
- sidekiq_options retry: 5, dead: false
+ sidekiq_options retry: 1, dead: false
sidekiq_options max_retries_after_interruption: 20
concurrency_limit -> { 4 }
@@ -20,6 +20,8 @@ class ReassignPlaceholderUserRecordsWorker
end
def perform(import_source_user_id, params = {})
+ raise StandardError, 'PG::QueryCanceled: ERROR: canceling statement due to statement timeout'
+
@import_source_user = Import::SourceUser.find_by_id(import_source_user_id)
return unless import_source_user_valid?
- Navigate to the import's top-level group's membership page, then to the "placeholders" tab, and assign a placeholder user to a real user. Then, accept the assignment (this can be done by impersonating the real assigned user, opening the reassignment notification email, and accepting).
- Accepting the reassignment begins the backend process to reassign all imported records to the real user. The exception added in step 2 should be thrown and cause the reassignment to fail. Allow the async worker to finish.
- Using GraphQL, query for the
ImportSourceUserthat just failed. ValidatereassignmentErrormatches the message thrown in step 2. - Verify that the reassignment error is also now visible in the UI
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
Related to #589777
