Skip to content

Commit

Permalink
Fixes ERR_PNPM_FETCH-HelperSubprocessFailed (#10398)
Browse files Browse the repository at this point in the history
* exeption handling for PNPM_FETCH errors
  • Loading branch information
sachin-sandhu authored Aug 10, 2024
1 parent 3b902a0 commit 6b1f289
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ def updated_pnpm_lock_content(pnpm_lock)
MISSING_PACKAGE = /ERR_PNPM_FETCH_404[ [^:print:]]+GET (?<dependency_url>.*): (?:Not Found)? - 404/
UNAUTHORIZED_PACKAGE = /ERR_PNPM_FETCH_401[ [^:print:]]+GET (?<dependency_url>.*): Unauthorized - 401/

# ERR_PNPM_FETCH ERROR CODES
ERR_PNPM_FETCH_401 = /ERR_PNPM_FETCH_401.*GET (?<dependency_url>.*): - 401/
ERR_PNPM_FETCH_403 = /ERR_PNPM_FETCH_403.*GET (?<dependency_url>.*): - 403/
ERR_PNPM_FETCH_500 = /ERR_PNPM_FETCH_500.*GET (?<dependency_url>.*): - 500/
ERR_PNPM_FETCH_502 = /ERR_PNPM_FETCH_502.*GET (?<dependency_url>.*): - 502/

def run_pnpm_update(pnpm_lock:)
SharedHelpers.in_a_temporary_repo_directory(base_dir, repo_contents_path) do
File.write(".npmrc", npmrc_content(pnpm_lock))
Expand Down Expand Up @@ -107,12 +113,12 @@ def handle_pnpm_lock_updater_error(error, pnpm_lock)
raise Dependabot::GitDependenciesNotReachable, url
end

[FORBIDDEN_PACKAGE, MISSING_PACKAGE, UNAUTHORIZED_PACKAGE].each do |regexp|
[FORBIDDEN_PACKAGE, MISSING_PACKAGE, UNAUTHORIZED_PACKAGE, ERR_PNPM_FETCH_401,
ERR_PNPM_FETCH_403, ERR_PNPM_FETCH_500, ERR_PNPM_FETCH_502].each do |regexp|
next unless error_message.match?(regexp)

dependency_url = error_message.match(regexp).named_captures["dependency_url"]

raise_package_access_error(dependency_url, pnpm_lock)
raise_package_access_error(error_message, dependency_url, pnpm_lock)
end

raise
Expand All @@ -125,7 +131,7 @@ def raise_resolvability_error(error_message, pnpm_lock)
raise Dependabot::DependencyFileNotResolvable, msg
end

def raise_package_access_error(dependency_url, pnpm_lock)
def raise_package_access_error(error_message, dependency_url, pnpm_lock)
package_name = RegistryParser.new(resolved_url: dependency_url, credentials: credentials).dependency_name
missing_dep = lockfile_dependencies(pnpm_lock)
.find { |dep| dep.name == package_name }
Expand All @@ -136,7 +142,7 @@ def raise_package_access_error(dependency_url, pnpm_lock)
credentials: credentials,
npmrc_file: npmrc_file
).registry

Dependabot.logger.warn("Error while accessing #{reg}. Response (truncated) - #{error_message[0..500]}...")
raise PrivateSourceAuthenticationFailure, reg
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -633,7 +633,7 @@ def handle_yarn_error(error, params)
).void
end
def handle_group_patterns(error, usage_error_message, params) # rubocop:disable Metrics/PerceivedComplexity
error_message = error.message
error_message = error.message.gsub(/\e\[\d+(;\d+)*m/, "")
VALIDATION_GROUP_PATTERNS.each do |group|
patterns = group[:patterns]
matchfn = group[:matchfn]
Expand All @@ -645,8 +645,8 @@ def handle_group_patterns(error, usage_error_message, params) # rubocop:disable
message = usage_error_message.empty? ? error_message : usage_error_message
if in_usage && pattern_in_message(patterns, usage_error_message)
raise create_error(handler, message, error, params)
elsif !in_usage && pattern_in_message(patterns, error.message)
raise create_error(handler, error.message, error, params)
elsif !in_usage && pattern_in_message(patterns, error_message)
raise create_error(handler, error_message, error, params)
end

raise create_error(handler, message, error, params) if matchfn&.call(usage_error_message, error_message)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,15 @@
end
end

context "when there is a private repo we don't have access to and returns a 4xx error" do
let(:project_name) { "pnpm/private_repo_no_access" }

it "raises a helpful error" do
expect { updated_pnpm_lock_content }
.to raise_error(Dependabot::PrivateSourceAuthenticationFailure)
end
end

context "with a private git dep we don't have access to" do
let(:dependency_name) { "cross-fetch" }
let(:version) { "4.0.0" }
Expand Down Expand Up @@ -167,6 +176,15 @@
end
end

context "when there is a private repo returns a 5xx error" do
let(:project_name) { "pnpm/private_repo_with_server_error" }

it "raises a helpful error" do
expect { updated_pnpm_lock_content }
.to raise_error(Dependabot::PrivateSourceAuthenticationFailure)
end
end

context "with a private git dep we don't have access to in PNPM v8" do
let(:dependency_name) { "cross-fetch" }
let(:version) { "4.0.0" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,21 +113,22 @@

context "when the error message contains a node version not satisfy regex and versions are extracted" do
let(:error_message) do
" YN0000: ┌ Project validation\n" \
"\e[94m➤\e[39m YN0000: · Yarn 4.0.2\n\e[94m➤\e[39m \e[90mYN0000\e[39m: ┌ Project validation\n" \
"::group::Project validation\n" \
"➤ YN0000: │ The current Node version v20.15.1 does not satisfy the required version 14.21.3.\n" \
"::endgroup::\n" \
"➤ YN0000: └ Completed\n" \
"➤ YN0000: Failed with errors in 0s 6ms"
"\e[91m➤\e[39m YN0000: │ \e[31mThe current \e[32mNode\e[39m\e[31m version \e[36m20.13.1\e[39m\e[31m does" \
" not satisfy the required version \e[36m20.11.0\e[39m\e[31m.\e[39m\n::endgroup::\n\e[91m➤\e[39m YN0000:" \
" \e[31mThe current \e[32mNode\e[39m\e[31m version \e[36m20.13.1\e[39m\e[31m does not satisfy the required " \
"version \e[36m20.11.0\e[39m\e[31m.\e[39m\n" \
"\e[94m➤\e[39m \e[90mYN0000\e[39m: └ Completed\n\e[91m➤\e[39m YN0000: · Failed with errors in 0s 3ms"
end

it "raises a ToolVersionNotSupported error with the correct versions" do
expect do
error_handler.handle_error(error, { yarn_lock: yarn_lock })
end.to raise_error(Dependabot::ToolVersionNotSupported) do |e| # rubocop:disable Style/MultilineBlockChain
expect(e.tool_name).to eq("Yarn")
expect(e.detected_version).to eq("v20.15.1")
expect(e.supported_versions).to eq("14.21.3")
expect(e.detected_version).to eq("20.13.1")
expect(e.supported_versions).to eq("20.11.0")
end
end
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@dsp-testing:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NPM_TOKEN}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"@dsp-testing/node": "1.0.3"
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@dsp-testing:registry=https://npm.pkg.github.com
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"@dsp-testing/is-positive": "3.1.0"
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6b1f289

Please sign in to comment.