Generic package uniqueness error
Problem
One of the more common errors in the package stage is:
ActiveRecord::RecordNotUnique
PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_packages_on_project_id_name_version_unique_when_generic"
<details><summary>Stack Trace</summary>
```sh
lib/gitlab/database/load_balancing/connection_proxy.rb:126:in `block in write_using_load_balancer',
lib/gitlab/database/load_balancing/load_balancer.rb:112:in `block in read_write',
lib/gitlab/database/load_balancing/load_balancer.rb:179:in `retry_with_backoff',
lib/gitlab/database/load_balancing/load_balancer.rb:110:in `read_write',
lib/gitlab/database/load_balancing/connection_proxy.rb:125:in `write_using_load_balancer',
lib/gitlab/database/load_balancing/connection_proxy.rb:67:in `block (2 levels) in <class:ConnectionProxy>',
lib/gitlab/database/load_balancing/connection_proxy.rb:126:in `block in write_using_load_balancer',
lib/gitlab/database/load_balancing/load_balancer.rb:112:in `block in read_write',
lib/gitlab/database/load_balancing/load_balancer.rb:179:in `retry_with_backoff',
lib/gitlab/database/load_balancing/load_balancer.rb:110:in `read_write',
lib/gitlab/database/load_balancing/connection_proxy.rb:125:in `write_using_load_balancer',
lib/gitlab/database/load_balancing/connection_proxy.rb:77:in `transaction',
lib/gitlab/database/load_balancing/connection_proxy.rb:126:in `block in write_using_load_balancer',
lib/gitlab/database/load_balancing/load_balancer.rb:112:in `block in read_write',
lib/gitlab/database/load_balancing/load_balancer.rb:179:in `retry_with_backoff',
lib/gitlab/database/load_balancing/load_balancer.rb:110:in `read_write',
lib/gitlab/database/load_balancing/connection_proxy.rb:125:in `write_using_load_balancer',
lib/gitlab/database/load_balancing/connection_proxy.rb:77:in `transaction',
lib/gitlab/database.rb:261:in `block in transaction',
lib/gitlab/database.rb:260:in `transaction',
app/services/packages/create_package_service.rb:14:in `find_or_create_package!',
app/services/packages/generic/find_or_create_package_service.rb:7:in `execute',
app/services/packages/generic/create_package_file_service.rb:24:in `find_or_create_package',
app/services/packages/generic/create_package_file_service.rb:8:in `block in execute',
lib/gitlab/database/load_balancing/connection_proxy.rb:126:in `block in write_using_load_balancer',
lib/gitlab/database/load_balancing/load_balancer.rb:112:in `block in read_write',
lib/gitlab/database/load_balancing/load_balancer.rb:179:in `retry_with_backoff',
lib/gitlab/database/load_balancing/load_balancer.rb:110:in `read_write',
lib/gitlab/database/load_balancing/connection_proxy.rb:125:in `write_using_load_balancer',
lib/gitlab/database/load_balancing/connection_proxy.rb:77:in `transaction',
lib/gitlab/database.rb:261:in `block in transaction',
lib/gitlab/database.rb:260:in `transaction',
app/services/packages/generic/create_package_file_service.rb:7:in `execute',
lib/api/generic_packages.rb:71:in `block (4 levels) in <class:GenericPackages>',
ee/lib/gitlab/middleware/ip_restrictor.rb:14:in `block in call',
ee/lib/gitlab/ip_address_state.rb:10:in `with',
ee/lib/gitlab/middleware/ip_restrictor.rb:13:in `call',
lib/api/api_guard.rb:213:in `call',
ee/lib/omni_auth/strategies/group_saml.rb:41:in `other_phase',
lib/gitlab/metrics/elasticsearch_rack_middleware.rb:16:in `call',
lib/gitlab/middleware/rails_queue_duration.rb:33:in `call',
lib/gitlab/middleware/speedscope.rb:13:in `call',
lib/gitlab/request_profiler/middleware.rb:17:in `call',
lib/gitlab/database/load_balancing/rack_middleware.rb:23:in `call',
lib/gitlab/metrics/rack_middleware.rb:16:in `block in call',
lib/gitlab/metrics/web_transaction.rb:46:in `run',
lib/gitlab/metrics/rack_middleware.rb:16:in `call',
lib/gitlab/jira/middleware.rb:19:in `call',
lib/gitlab/middleware/go.rb:20:in `call',
lib/gitlab/etag_caching/middleware.rb:21:in `call',
lib/gitlab/middleware/multipart.rb:178:in `block in call',
lib/gitlab/middleware/multipart.rb:63:in `with_open_files',
lib/gitlab/middleware/multipart.rb:177:in `call',
lib/gitlab/middleware/read_only/controller.rb:50:in `call',
lib/gitlab/middleware/read_only.rb:18:in `call',
lib/gitlab/middleware/same_site_cookies.rb:27:in `call',
lib/gitlab/middleware/handle_malformed_strings.rb:21:in `call',
lib/gitlab/middleware/basic_health_check.rb:25:in `call',
lib/gitlab/middleware/handle_ip_spoof_attack_error.rb:25:in `call',
lib/gitlab/middleware/request_context.rb:21:in `call',
config/initializers/fix_local_cache_middleware.rb:11:in `call',
lib/gitlab/middleware/compressed_json.rb:26:in `call',
lib/gitlab/middleware/rack_multipart_tempfile_factory.rb:19:in `call',
lib/gitlab/middleware/sidekiq_web_static.rb:20:in `call',
lib/gitlab/metrics/requests_rack_middleware.rb:75:in `call',
lib/gitlab/middleware/release_env.rb:13:in `call'
This seems to occur only for Generic packages.
Expected Behavior
We have a uniqueness model validation on these columns: https://gitlab.com/gitlab-org/gitlab/-/blob/e385c50a1c75f43072d3074c1c5e31e56c47fa8a/app/models/packages/package.rb#L62, so we should see a 422
error rather than a 500
error.
Proposal
Find out why we are getting all the way to the database level before hitting this error rather than hitting it at the model level. Update the code so we see the appropriate 422
error.