From c599b9593d9963e09b1dea0503bcd1788b4df3e6 Mon Sep 17 00:00:00 2001 From: Kassio Borges <kborges@gitlab.com> Date: Sat, 22 Apr 2023 15:40:39 +0000 Subject: [PATCH] Do not block project overview when wiki repository fails Changelog: fixed --- app/controllers/concerns/wiki_actions.rb | 6 ++++ app/models/wiki.rb | 9 +++-- .../shared/empty_states/_wikis.html.haml | 3 +- app/views/shared/wikis/empty.html.haml | 10 +++++- locale/gitlab.pot | 3 ++ .../projects/wikis_controller_spec.rb | 2 +- .../wiki_actions_shared_examples.rb | 33 ++++++++++++------ .../models/wiki_shared_examples.rb | 34 +++++++++++++++++++ 8 files changed, 85 insertions(+), 15 deletions(-) diff --git a/app/controllers/concerns/wiki_actions.rb b/app/controllers/concerns/wiki_actions.rb index 08604a15e8a48..a007abacacc8e 100644 --- a/app/controllers/concerns/wiki_actions.rb +++ b/app/controllers/concerns/wiki_actions.rb @@ -55,6 +55,12 @@ module WikiActions render 'shared/wikis/git_error' end + + rescue_from Gitlab::Git::Repository::NoRepository do + @error = _('Could not access the Wiki Repository at this time.') + + render 'shared/wikis/empty' + end end def new diff --git a/app/models/wiki.rb b/app/models/wiki.rb index da8be7304e8ba..39d22ea0e0759 100644 --- a/app/models/wiki.rb +++ b/app/models/wiki.rb @@ -6,6 +6,7 @@ class Wiki include Repositories::CanHousekeepRepository include Gitlab::Utils::StrongMemoize include GlobalID::Identification + include Gitlab::Git::WrapsGitalyErrors extend ActiveModel::Naming @@ -185,6 +186,8 @@ def create_wiki_repository def has_home_page? !!find_page(HOMEPAGE) + rescue StandardError + false end def empty? @@ -413,7 +416,7 @@ def cleanup end def capture_git_error(action, &block) - yield block + wrapped_gitaly_errors(&block) rescue Gitlab::Git::Index::IndexError, Gitlab::Git::CommitError, Gitlab::Git::PreReceiveError, @@ -491,7 +494,9 @@ def find_matched_file(title, version) escaped_path = RE2::Regexp.escape(sluggified_title(title)) path_regexp = Gitlab::EncodingHelper.encode_utf8_no_detect("(?i)^#{escaped_path}\\.(#{file_extension_regexp})$") - matched_files = repository.search_files_by_regexp(path_regexp, version, limit: 1) + matched_files = capture_git_error(:find) do + repository.search_files_by_regexp(path_regexp, version, limit: 1) + end return if matched_files.blank? Gitlab::EncodingHelper.encode_utf8_no_detect(matched_files.first) diff --git a/app/views/shared/empty_states/_wikis.html.haml b/app/views/shared/empty_states/_wikis.html.haml index 8304a2f18a0a6..57f1c9d381e7a 100644 --- a/app/views/shared/empty_states/_wikis.html.haml +++ b/app/views/shared/empty_states/_wikis.html.haml @@ -1,7 +1,8 @@ - layout_path = 'shared/empty_states/wikis_layout' - messages = wiki_empty_state_messages(@wiki) +- hide_create = local_assigns[:hide_create] -- if can?(current_user, :create_wiki, @wiki.container) +- if !hide_create && can?(current_user, :create_wiki, @wiki.container) - create_path = wiki_page_path(@wiki, params[:id], view: 'create') - create_link = link_to s_('WikiEmpty|Create your first page'), create_path, class: 'btn gl-button btn-confirm', title: s_('WikiEmpty|Create your first page'), data: { qa_selector: 'create_first_page_link' } diff --git a/app/views/shared/wikis/empty.html.haml b/app/views/shared/wikis/empty.html.haml index c52ead74b4ceb..d30a37aaa3ebc 100644 --- a/app/views/shared/wikis/empty.html.haml +++ b/app/views/shared/wikis/empty.html.haml @@ -2,4 +2,12 @@ - @right_sidebar = false - add_page_specific_style 'page_bundles/wiki' -= render 'shared/empty_states/wikis' +- if @error.present? + = render Pajamas::AlertComponent.new(alert_options: { id: 'error_explanation', class: 'gl-mb-3'}, + dismissible: false, + variant: :danger) do |c| + = c.body do + %ul.gl-pl-4 + = @error + += render 'shared/empty_states/wikis', hide_create: @error.present? diff --git a/locale/gitlab.pot b/locale/gitlab.pot index a2affaeb776aa..546e454e4403a 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -12041,6 +12041,9 @@ msgstr "" msgid "CorpusManagement|Total Size: %{totalSize}" msgstr "" +msgid "Could not access the Wiki Repository at this time." +msgstr "" + msgid "Could not add admins as members" msgstr "" diff --git a/spec/controllers/projects/wikis_controller_spec.rb b/spec/controllers/projects/wikis_controller_spec.rb index 7243588681dd4..353cd62686f15 100644 --- a/spec/controllers/projects/wikis_controller_spec.rb +++ b/spec/controllers/projects/wikis_controller_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Projects::WikisController do +RSpec.describe Projects::WikisController, feature_category: :wiki do it_behaves_like 'wiki controller actions' do let(:container) { create(:project, :public, namespace: user.namespace) } let(:routing_params) { { namespace_id: container.namespace, project_id: container } } diff --git a/spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb b/spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb index 5d77ed5fdfc80..768b54dc73e6f 100644 --- a/spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb +++ b/spec/support/shared_examples/controllers/wiki_actions_shared_examples.rb @@ -15,20 +15,33 @@ sign_in(user) end - shared_examples 'recovers from git timeout' do + shared_examples 'recovers from git errors' do let(:method_name) { :page } - context 'when we encounter git command errors' do + context 'when we encounter CommandTimedOut error' do it 'renders the appropriate template', :aggregate_failures do - expect(controller).to receive(method_name) do - raise ::Gitlab::Git::CommandTimedOut, 'Deadline Exceeded' - end + expect(controller) + .to receive(method_name) + .and_raise(::Gitlab::Git::CommandTimedOut, 'Deadline Exceeded') request expect(response).to render_template('shared/wikis/git_error') end end + + context 'when we encounter a NoRepository error' do + it 'renders the appropriate template', :aggregate_failures do + expect(controller) + .to receive(method_name) + .and_raise(Gitlab::Git::Repository::NoRepository) + + request + + expect(response).to render_template('shared/wikis/empty') + expect(assigns(:error)).to eq('Could not access the Wiki Repository at this time.') + end + end end describe 'GET #new' do @@ -65,7 +78,7 @@ get :pages, params: routing_params.merge(id: wiki_title) end - it_behaves_like 'recovers from git timeout' do + it_behaves_like 'recovers from git errors' do subject(:request) { get :pages, params: routing_params.merge(id: wiki_title) } let(:method_name) { :wiki_pages } @@ -122,7 +135,7 @@ end end - it_behaves_like 'recovers from git timeout' do + it_behaves_like 'recovers from git errors' do subject(:request) { get :history, params: routing_params.merge(id: wiki_title) } let(:allow_read_wiki) { true } @@ -170,7 +183,7 @@ end end - it_behaves_like 'recovers from git timeout' do + it_behaves_like 'recovers from git errors' do subject(:request) { get :diff, params: routing_params.merge(id: wiki_title, version_id: wiki.repository.commit.id) } end end @@ -185,7 +198,7 @@ context 'when page exists' do let(:id) { wiki_title } - it_behaves_like 'recovers from git timeout' + it_behaves_like 'recovers from git errors' it 'renders the page' do request @@ -366,7 +379,7 @@ subject(:request) { get(:edit, params: routing_params.merge(id: id_param)) } it_behaves_like 'edit action' - it_behaves_like 'recovers from git timeout' + it_behaves_like 'recovers from git errors' context 'when page content encoding is valid' do render_views diff --git a/spec/support/shared_examples/models/wiki_shared_examples.rb b/spec/support/shared_examples/models/wiki_shared_examples.rb index b0a63a1332e90..017e51ecd242f 100644 --- a/spec/support/shared_examples/models/wiki_shared_examples.rb +++ b/spec/support/shared_examples/models/wiki_shared_examples.rb @@ -94,6 +94,40 @@ end end + describe '#has_home_page?' do + context 'when home page exists' do + before do + wiki.repository.create_file( + user, + 'home.md', + 'home file', + branch_name: wiki.default_branch, + message: "created home page", + author_email: user.email, + author_name: user.name + ) + end + + it 'returns true' do + expect(wiki.has_home_page?).to eq(true) + end + + it 'returns false when #find_page raise an error' do + allow(wiki) + .to receive(:find_page) + .and_raise(StandardError) + + expect(wiki.has_home_page?).to eq(false) + end + end + + context 'when home page does not exist' do + it 'returns false' do + expect(wiki.has_home_page?).to eq(false) + end + end + end + describe '#to_global_id' do it 'returns a global ID' do expect(wiki.to_global_id.to_s).to eq("gid://gitlab/#{wiki.class.name}/#{wiki.id}") -- GitLab