Commit c62d89cd authored by Stan Hu's avatar Stan Hu

Update project export job status upon failure

When a project export is initiated, we create a `ProjectExportJob`
database record that tracks the progress of the Sidekiq job. If an
export fails, the record may cause the project export status to
indicate "in progress" or "regeneration in progress" until the
`StuckExportJobsWorker` comes along and updates the status as failed.

We can expedite this process by handling failures and marking the job
status appropriately.

Relates to https://gitlab.com/gitlab-org/gitlab/-/issues/351155

Changelog: fixed
parent cc8589dc
......@@ -24,8 +24,15 @@ class ProjectExportWorker # rubocop:disable Scalability/IdempotentWorker
::Projects::ImportExport::ExportService.new(project, current_user, params).execute(after_export)
export_job&.finish
rescue ActiveRecord::RecordNotFound, Gitlab::ImportExport::AfterExportStrategyBuilder::StrategyNotFoundError => e
logger.error("Failed to export project #{project_id}: #{e.message}")
rescue ActiveRecord::RecordNotFound => e
log_failure(project_id, e)
rescue Gitlab::ImportExport::AfterExportStrategyBuilder::StrategyNotFoundError => e
log_failure(project_id, e)
export_job&.finish
rescue StandardError => e
log_failure(project_id, e)
export_job&.fail_op
raise
end
private
......@@ -35,4 +42,8 @@ class ProjectExportWorker # rubocop:disable Scalability/IdempotentWorker
Gitlab::ImportExport::AfterExportStrategyBuilder.build!(strategy_klass, after_export_strategy)
end
def log_failure(project_id, ex)
logger.error("Failed to export project #{project_id}: #{ex.message}")
end
end
......@@ -53,6 +53,10 @@ RSpec.shared_examples 'export worker' do
it 'does not raise an exception when strategy is invalid' do
expect(::Projects::ImportExport::ExportService).not_to receive(:new)
expect_next_instance_of(ProjectExportJob) do |job|
expect(job).to receive(:finish)
end
expect { subject.perform(user.id, project.id, { 'klass' => 'Whatever' }) }.not_to raise_error
end
......@@ -63,6 +67,18 @@ RSpec.shared_examples 'export worker' do
it 'does not raise error when user cannot be found' do
expect { subject.perform(non_existing_record_id, project.id, {}) }.not_to raise_error
end
it 'fails the export job status' do
expect_next_instance_of(::Projects::ImportExport::ExportService) do |service|
expect(service).to receive(:execute).and_raise(Gitlab::ImportExport::Error)
end
expect_next_instance_of(ProjectExportJob) do |job|
expect(job).to receive(:fail_op)
end
expect { subject.perform(user.id, project.id, {}) }.to raise_error(Gitlab::ImportExport::Error)
end
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment