Searching for a term that returns documents in Elasticsearch belonging to a project that does not exist in the database results in a 500 error
Summary
When searching for a term that returns documents in Elasticsearch belonging to a project that has since been deleted in the GitLab database, a 500 error is thrown:
ActionView::Template::Error (undefined method `repository' for nil:NilClass):
97: = link_to search_filter_path(scope: 'commits') do
98: = _("Commits")
99: %span.badge.badge-pill
100: = limited_count(@search_results.commits_count)
101: %li{ class: active_when(@scope == 'wiki_blobs') }
102: = link_to search_filter_path(scope: 'wiki_blobs') do
103: = _("Wiki")
I managed to trace the error back to https://gitlab.com/gitlab-org/gitlab-ee/blob/v11.10.4-ee/ee/app/models/concerns/elastic/repositories_search.rb#L66, where project.repository.raw
is called.
We should add a guard clause here in the map to return nil
if project
is nil
and compact
the array after, or similar.
This was reported (Zendesk, internal use only) by a 6,500-seat premium customer.
Steps to reproduce
I'm not sure how to reproduce this as I believe (but am not confident) that we have callbacks set up to delete documents from the Elasticsearch index when a project is deleted. Perhaps I'm mistaken?
Example Project
(If possible, please create an example project here on GitLab.com that exhibits the problematic behavior, and link to it here in the bug report)
(If you are using an older version of GitLab, this will also determine whether the bug is fixed in a more recent version)
What is the current bug behavior?
Search page results in an error.
What is the expected correct behavior?
Search page shouldn't result in an error.
Relevant logs and/or screenshots
I wrote a small Rails console snippet for the customer to test if my hypothesis was correct:
response = Repository.search('query_goes_here', type: :commit, options: {:has_parent=>{:parent_type=>"project", :query=>{:bool=>{:should=>[{:exists=>{:field=>"id"}}, {:bool=>{:filter=>[{:term=>{:visibility_level=>20}}, {:term=>{:repository_access_level=>20}}]}}, {:bool=>{:filter=>[{:term=>{:visibility_level=>10}}, {:term=>{:repository_access_level=>20}}]}}], :must_not=>{:term=>{:repository_access_level=>0}}}}}})[:commits][:results]
project_ids = response.map { |result| result["_source"]["commit"]["rid"] }
db_project_ids = Project.includes(:route).where(id: project_ids).pluck(:id)
Confirmed as 12404
was present in project_ids
but not db_project_ids
:
# project_ids
["14921", "18302", "20177", "23410", "10833", "17334", "7927", "7927", "18773", "20676", "21907", "24225", "14020", "18359", "12404", "19815", "18919", "17926", "18152", "18285"]
# db_project_ids
[7927, 10833, 14020, 14921, 17334, 17926, 18152, 18285, 18302, 18359, 18773, 18919, 19815, 20177, 20676, 21907, 23410, 24225]
Output of checks
(If you are reporting a bug on GitLab.com, write: This bug happens on GitLab.com)
Results of GitLab environment info
Expand for output related to GitLab environment info
(For installations with omnibus-gitlab package run and paste the output of:
sudo gitlab-rake gitlab:env:info
)(For installations from source run and paste the output of:
sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production
)
Results of GitLab application Check
Expand for output related to the GitLab application check
(For installations with omnibus-gitlab package run and paste the output of:
sudo gitlab-rake gitlab:check SANITIZE=true
)(For installations from source run and paste the output of:
sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production SANITIZE=true
)(we will only investigate if the tests are passing)
Possible fixes
(If you can, link to the line of code that might be responsible for the problem)