Commit 1dd45193 authored by Harsha Muralidhar's avatar Harsha Muralidhar Committed by Francisco Javier López

Handle git exceptions in wiki create and update services

In this commit, we wrap git operations when creating and updating
wiki pages, in order to avoid throwing git errors when operations
fails.

Changelog: fixed
parent 9e532e95
...@@ -278,6 +278,19 @@ class Wiki ...@@ -278,6 +278,19 @@ class Wiki
@repository = nil @repository = nil
end end
def capture_git_error(action, &block)
yield block
rescue Gitlab::Git::Index::IndexError,
Gitlab::Git::CommitError,
Gitlab::Git::PreReceiveError,
Gitlab::Git::CommandError,
ArgumentError => error
Gitlab::ErrorTracking.log_exception(error, action: action, wiki_id: id)
false
end
private private
def multi_commit_options(action, message = nil, title = nil) def multi_commit_options(action, message = nil, title = nil)
...@@ -311,19 +324,6 @@ class Wiki ...@@ -311,19 +324,6 @@ class Wiki
"#{user.username} #{action} page: #{title}" "#{user.username} #{action} page: #{title}"
end end
def capture_git_error(action, &block)
yield block
rescue Gitlab::Git::Index::IndexError,
Gitlab::Git::CommitError,
Gitlab::Git::PreReceiveError,
Gitlab::Git::CommandError,
ArgumentError => error
Gitlab::ErrorTracking.log_exception(error, action: action, wiki_id: id)
false
end
def change_head_to_default_branch def change_head_to_default_branch
repository.raw_repository.write_ref('HEAD', "refs/heads/#{default_branch}") repository.raw_repository.write_ref('HEAD', "refs/heads/#{default_branch}")
end end
......
...@@ -6,11 +6,12 @@ module WikiPages ...@@ -6,11 +6,12 @@ module WikiPages
wiki = Wiki.for_container(container, current_user) wiki = Wiki.for_container(container, current_user)
page = WikiPage.new(wiki) page = WikiPage.new(wiki)
if page.create(@params) wiki.capture_git_error(event_action) do
execute_hooks(page) page.create(@params)
end end
if page.persisted? if page.persisted?
execute_hooks(page)
ServiceResponse.success(payload: { page: page }) ServiceResponse.success(payload: { page: page })
else else
ServiceResponse.error(message: _('Could not create wiki page'), payload: { page: page }) ServiceResponse.error(message: _('Could not create wiki page'), payload: { page: page })
......
...@@ -8,7 +8,7 @@ module WikiPages ...@@ -8,7 +8,7 @@ module WikiPages
# this class is not thread safe! # this class is not thread safe!
@old_slug = page.slug @old_slug = page.slug
if page.update(@params) if page.wiki.capture_git_error(event_action) { page.update(@params) }
execute_hooks(page) execute_hooks(page)
ServiceResponse.success(payload: { page: page }) ServiceResponse.success(payload: { page: page })
else else
......
...@@ -4,4 +4,24 @@ require 'spec_helper' ...@@ -4,4 +4,24 @@ require 'spec_helper'
RSpec.describe WikiPages::CreateService do RSpec.describe WikiPages::CreateService do
it_behaves_like 'WikiPages::CreateService#execute', :project it_behaves_like 'WikiPages::CreateService#execute', :project
describe '#execute' do
let_it_be(:project) { create(:project) }
subject(:service) { described_class.new(container: project) }
context 'when wiki create fails due to git error' do
let(:wiki_git_error) { 'Could not create wiki page' }
it 'catches the thrown error and returns a ServiceResponse error' do
allow_next_instance_of(WikiPage) do |instance|
allow(instance).to receive(:create).and_raise(Gitlab::Git::CommandError.new(wiki_git_error))
end
result = service.execute
expect(result).to be_error
expect(result.message).to eq(wiki_git_error)
end
end
end
end end
...@@ -4,4 +4,26 @@ require 'spec_helper' ...@@ -4,4 +4,26 @@ require 'spec_helper'
RSpec.describe WikiPages::UpdateService do RSpec.describe WikiPages::UpdateService do
it_behaves_like 'WikiPages::UpdateService#execute', :project it_behaves_like 'WikiPages::UpdateService#execute', :project
describe '#execute' do
let_it_be(:project) { create(:project) }
let(:page) { create(:wiki_page, project: project) }
subject(:service) { described_class.new(container: project) }
context 'when wiki create fails due to git error' do
let(:wiki_git_error) { 'Could not update wiki page' }
it 'catches the thrown error and returns a ServiceResponse error' do
allow_next_instance_of(WikiPage) do |instance|
allow(instance).to receive(:update).and_raise(Gitlab::Git::CommandError.new(wiki_git_error))
end
result = service.execute(page)
expect(result).to be_error
expect(result.message).to eq(wiki_git_error)
end
end
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