diff --git a/npm_and_yarn/lib/dependabot/npm_and_yarn.rb b/npm_and_yarn/lib/dependabot/npm_and_yarn.rb index 4cadade7fa..8ce4bb7869 100644 --- a/npm_and_yarn/lib/dependabot/npm_and_yarn.rb +++ b/npm_and_yarn/lib/dependabot/npm_and_yarn.rb @@ -160,6 +160,11 @@ module NpmAndYarn AUTH_ERROR: /YN0001:*.*Fatal Error: could not read Username for '(?.*)': terminal prompts disabled/ }.freeze, T::Hash[String, Regexp]) + YN0001_REQ_NOT_FOUND_CODES = T.let({ + REQUIREMENT_NOT_SATISFIED: /provides (?.*)(.*?)with version (?.*), which doesn't satisfy what (?.*) requests/, # rubocop:disable Layout/LineLength + REQUIREMENT_NOT_PROVIDED: /(?.*)(.*?)doesn't provide (?.*)(.*?), requested by (?.*)/ + }.freeze, T::Hash[String, Regexp]) + class Utils extend T::Sig @@ -212,6 +217,13 @@ def self.sanitize_resolvability_message(error_message, dependencies, yarn_lock) return Dependabot::PrivateSourceAuthenticationFailure.new(url) end end + + YN0001_REQ_NOT_FOUND_CODES.each do |(_yn0001_key, yn0001_regex)| + if (msg = message.match(yn0001_regex)) + return Dependabot::DependencyFileNotResolvable.new(msg) + end + end + Dependabot::DependabotError.new(message) } }, diff --git a/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/latest_version_finder.rb b/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/latest_version_finder.rb index 76597344e4..be83b64611 100644 --- a/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/latest_version_finder.rb +++ b/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/latest_version_finder.rb @@ -329,6 +329,8 @@ def fetch_npm_response password: password } ) + rescue URI::InvalidURIError => e + raise DependencyFileNotResolvable, e.message end def check_npm_response(npm_response) diff --git a/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/registry_finder.rb b/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/registry_finder.rb index 7f4bde5144..3ad848f671 100644 --- a/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/registry_finder.rb +++ b/npm_and_yarn/lib/dependabot/npm_and_yarn/update_checker/registry_finder.rb @@ -90,6 +90,8 @@ def first_registry_with_dependency_details Excon::Error::Socket, JSON::ParserError nil + rescue URI::InvalidURIError => e + raise DependencyFileNotResolvable, e.message end&.fetch("registry") @first_registry_with_dependency_details ||= global_registry.sub(%r{/+$}, "").sub(%r{^.*?//}, "") diff --git a/npm_and_yarn/spec/dependabot/npm_and_yarn/update_checker/latest_version_finder_spec.rb b/npm_and_yarn/spec/dependabot/npm_and_yarn/update_checker/latest_version_finder_spec.rb index 42f6af8d13..d7eaf5eec2 100644 --- a/npm_and_yarn/spec/dependabot/npm_and_yarn/update_checker/latest_version_finder_spec.rb +++ b/npm_and_yarn/spec/dependabot/npm_and_yarn/update_checker/latest_version_finder_spec.rb @@ -940,6 +940,22 @@ end end end + + context "when the npm registry uri is invalid and lookup returns a bad URI error" do + before do + stub_request(:get, registry_listing_url) + .to_return(status: 500, body: '{"error":"bad URI(is not URI?): "https://registry.npmjs.org/\"/webpack""}') + + allow(version_finder).to receive(:sleep).and_return(true) + end + + it "raises an error" do + expect { version_finder.latest_version_from_registry } + .to raise_error do |err| + expect(err.class).to eq(Dependabot::DependencyFileNotResolvable) + end + end + end end describe "#latest_version_with_no_unlock" do diff --git a/npm_and_yarn/spec/dependabot/npm_and_yarn/yarn_error_handler_spec.rb b/npm_and_yarn/spec/dependabot/npm_and_yarn/yarn_error_handler_spec.rb index 5aa9c672a1..fc3f533963 100644 --- a/npm_and_yarn/spec/dependabot/npm_and_yarn/yarn_error_handler_spec.rb +++ b/npm_and_yarn/spec/dependabot/npm_and_yarn/yarn_error_handler_spec.rb @@ -210,6 +210,20 @@ end end + context "when the error message contains requirement not specified error" do + let(:error_message) do + "[YN0001]: Exception error, Detail: ➤ YN0000: ┌ Resolution step" \ + "kubernetes-dashboard@workspace:. provides @angular/core (pc7ae5) with version 16.2.1, which doesn't satisfy what codelyzer requests" # rubocop:disable Layout/LineLength + end + + it "raises a DependencyFileNotResolvable error with the correct message" do + expect do + error_handler.handle_yarn_error(error, { yarn_lock: yarn_lock }) + end.to raise_error(Dependabot::DependencyFileNotResolvable, + "provides @angular/core (pc7ae5) with version 16.2.1, which doesn't satisfy what codelyzer requests") # rubocop:disable Layout/LineLength + end + end + context "when the error message contains YN0041 response (Invalid authentication)" do let(:error_message) do "[91m➤ YN0041: │ @cadence-group/conventional-changelog-angular-" \