Commit f2375df8 authored by Peter Leitzen's avatar Peter Leitzen

Merge branch 'vij-snippet-create-update-errors' into 'master'

Handle snippet file path errors in services

See merge request gitlab-org/gitlab!31333
parents b9a8d445 23639b80
......@@ -65,11 +65,12 @@ module SnippetsActions
params[:line_ending] == 'raw' ? content : content.gsub(/\r\n/, "\n")
end
def check_repository_error
repository_errors = Array(snippet.errors.delete(:repository))
def handle_repository_error(action)
errors = Array(snippet.errors.delete(:repository))
flash.now[:alert] = repository_errors.first if repository_errors.present?
recaptcha_check_with_fallback(repository_errors.empty?) { render :edit }
flash.now[:alert] = errors.first if errors.present?
recaptcha_check_with_fallback(errors.empty?) { render action }
end
def redirect_if_binary
......
......@@ -52,15 +52,8 @@ class Projects::SnippetsController < Projects::ApplicationController
create_params = snippet_params.merge(spammable_params)
service_response = Snippets::CreateService.new(project, current_user, create_params).execute
@snippet = service_response.payload[:snippet]
repository_operation_error = service_response.error? && !@snippet.persisted? && @snippet.valid?
if repository_operation_error
flash.now[:alert] = service_response.message
render :new
else
recaptcha_check_with_fallback { render :new }
end
handle_repository_error(:new)
end
def update
......@@ -69,7 +62,7 @@ class Projects::SnippetsController < Projects::ApplicationController
service_response = Snippets::UpdateService.new(project, current_user, update_params).execute(@snippet)
@snippet = service_response.payload[:snippet]
check_repository_error
handle_repository_error(:edit)
end
def show
......
......@@ -52,12 +52,9 @@ class SnippetsController < ApplicationController
create_params = snippet_params.merge(spammable_params)
service_response = Snippets::CreateService.new(nil, current_user, create_params).execute
@snippet = service_response.payload[:snippet]
repository_operation_error = service_response.error? && !@snippet.persisted? && @snippet.valid?
if repository_operation_error
flash.now[:alert] = service_response.message
render :new
if service_response.error? && @snippet.errors[:repository].present?
handle_repository_error(:new)
else
move_temporary_files if @snippet.valid? && params[:files]
......@@ -71,7 +68,7 @@ class SnippetsController < ApplicationController
service_response = Snippets::UpdateService.new(nil, current_user, update_params).execute(@snippet)
@snippet = service_response.payload[:snippet]
check_repository_error
handle_repository_error(:edit)
end
def show
......
......@@ -44,6 +44,9 @@ class SnippetRepository < ApplicationRecord
Gitlab::Git::PreReceiveError,
Gitlab::Git::CommandError,
ArgumentError => error
logger.error(message: "Snippet git error. Reason: #{error.message}", snippet: snippet.id)
raise commit_error_exception(error)
end
......@@ -91,7 +94,7 @@ class SnippetRepository < ApplicationRecord
def commit_error_exception(err)
if invalid_path_error?(err)
InvalidPathError.new('Invalid Path') # To avoid returning the message with the path included
InvalidPathError.new('Invalid file name') # To avoid returning the message with the path included
elsif invalid_signature_error?(err)
InvalidSignatureError.new(err.message)
else
......
......@@ -11,5 +11,22 @@ module Snippets
payload: { snippet: snippet }
)
end
def add_snippet_repository_error(snippet:, error:)
message = repository_error_message(error)
snippet.errors.add(:repository, message)
end
def repository_error_message(error)
message = self.is_a?(Snippets::CreateService) ? _("Error creating the snippet") : _("Error updating the snippet")
# We only want to include additional error detail in the message
# if the error is not a CommitError because we cannot guarantee the message
# will be user-friendly
message += " - #{error.message}" unless error.instance_of?(SnippetRepository::CommitError)
message
end
end
end
......@@ -60,7 +60,7 @@ module Snippets
@snippet = @snippet.dup
end
@snippet.errors.add(:base, e.message)
add_snippet_repository_error(snippet: @snippet, error: e)
false
end
......
......@@ -54,7 +54,8 @@ module Snippets
snippet.save
end
snippet.errors.add(:repository, 'Error updating the snippet')
add_snippet_repository_error(snippet: snippet, error: e)
log_error(e.message)
# If the commit action failed we remove it because
......
---
title: Modify Snippet git path errors to be more helpful
merge_request: 31333
author:
type: changed
......@@ -8459,6 +8459,9 @@ msgstr ""
msgid "Error creating new iteration"
msgstr ""
msgid "Error creating the snippet"
msgstr ""
msgid "Error deleting %{issuableType}"
msgstr ""
......@@ -8579,6 +8582,9 @@ msgstr ""
msgid "Error updating status of to-do item."
msgstr ""
msgid "Error updating the snippet"
msgstr ""
msgid "Error uploading file"
msgstr ""
......
......@@ -99,7 +99,7 @@ shared_examples_for 'snippet editor' do
end
context 'when the git operation fails' do
let(:error) { 'This is a git error' }
let(:error) { 'Error creating the snippet' }
before do
allow_next_instance_of(Snippets::CreateService) do |instance|
......
......@@ -42,7 +42,7 @@ describe 'Projects > Snippets > User updates a snippet', :js do
context 'when the git operation fails' do
before do
allow_next_instance_of(Snippets::UpdateService) do |instance|
allow(instance).to receive(:create_commit).and_raise(StandardError)
allow(instance).to receive(:create_commit).and_raise(StandardError, 'Error Message')
end
fill_in('project_snippet_title', with: 'Snippet new title')
......@@ -52,7 +52,7 @@ describe 'Projects > Snippets > User updates a snippet', :js do
end
it 'renders edit page and displays the error' do
expect(page.find('.flash-container span').text).to eq('Error updating the snippet')
expect(page.find('.flash-container span').text).to eq('Error updating the snippet - Error Message')
expect(page).to have_content('Edit Snippet')
end
end
......
......@@ -79,7 +79,7 @@ shared_examples_for 'snippet editor' do
end
context 'when the git operation fails' do
let(:error) { 'This is a git error' }
let(:error) { 'Error creating the snippet' }
before do
allow_next_instance_of(Snippets::CreateService) do |instance|
......
......@@ -73,7 +73,7 @@ describe 'User edits snippet', :js do
context 'when the git operation fails' do
before do
allow_next_instance_of(Snippets::UpdateService) do |instance|
allow(instance).to receive(:create_commit).and_raise(StandardError)
allow(instance).to receive(:create_commit).and_raise(StandardError, 'Error Message')
end
fill_in 'personal_snippet_title', with: 'New Snippet Title'
......@@ -83,7 +83,7 @@ describe 'User edits snippet', :js do
end
it 'renders edit page and displays the error' do
expect(page.find('.flash-container span').text).to eq('Error updating the snippet')
expect(page.find('.flash-container span').text).to eq('Error updating the snippet - Error Message')
expect(page).to have_content('Edit Snippet')
end
end
......
......@@ -169,8 +169,8 @@ describe Snippets::CreateService do
expect { subject }.not_to change { Snippet.count }
end
it 'returns the error' do
expect(snippet.errors.full_messages).to include('Repository could not be created')
it 'returns a generic creation error' do
expect(snippet.errors[:repository]).to eq ['Error creating the snippet - Repository could not be created']
end
it 'does not return a snippet with an id' do
......@@ -178,6 +178,14 @@ describe Snippets::CreateService do
end
end
context 'when repository creation fails with invalid file name' do
let(:extra_opts) { { file_name: 'invalid://file/name/here' } }
it 'returns an appropriate error' do
expect(snippet.errors[:repository]).to eq ['Error creating the snippet - Invalid file name']
end
end
context 'when the commit action fails' do
before do
allow_next_instance_of(SnippetRepository) do |instance|
......@@ -209,11 +217,11 @@ describe Snippets::CreateService do
subject
end
it 'returns the error' do
it 'returns a generic error' do
response = subject
expect(response).to be_error
expect(response.payload[:snippet].errors.full_messages).to eq ['foobar']
expect(response.payload[:snippet].errors[:repository]).to eq ['Error creating the snippet']
end
end
......
......@@ -121,7 +121,7 @@ describe Snippets::UpdateService do
response = subject
expect(response).to be_error
expect(response.payload[:snippet].errors[:repository].to_sentence).to eq 'Error updating the snippet'
expect(response.payload[:snippet].errors[:repository].to_sentence).to eq 'Error updating the snippet - Repository could not be created'
end
it 'does not try to commit file' do
......
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