Skip to content

Commit

Permalink
Surface out of disk/memory error message for easier visibility (depen…
Browse files Browse the repository at this point in the history
…dabot#9064)

* added out of disk error message to the go module updater

* surface out of memory error for yarn lock file parser operation

* Add test for memory error

* fixed failed test cases

* added out of disk and out of memory error to the workspace

* added out of memory/disk error to correct layer (run_shell_command)
  • Loading branch information
honeyankit committed Feb 17, 2024
1 parent dfe50fe commit c676f59
Show file tree
Hide file tree
Showing 7 changed files with 103 additions and 3 deletions.
20 changes: 19 additions & 1 deletion common/lib/dependabot/shared_helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -405,7 +405,6 @@ def self.run_shell_command(command,
stderr_to_stdout: true)
start = Time.now
cmd = allow_unsafe_shell_command ? command : escape_command(command)

if stderr_to_stdout
stdout, process = Open3.capture2e(env || {}, cmd)
else
Expand All @@ -425,12 +424,31 @@ def self.run_shell_command(command,
process_exit_value: process.to_s
}

check_out_of_disk_memory_error(stderr, error_context)

raise SharedHelpers::HelperSubprocessFailed.new(
message: stderr_to_stdout ? stdout : "#{stderr}\n#{stdout}",
error_context: error_context
)
end

sig { params(stderr: T.nilable(String), error_context: T::Hash[Symbol, String]).void }
def self.check_out_of_disk_memory_error(stderr, error_context)
if stderr&.include?("No space left on device") || stderr&.include?("Out of diskspace")
raise HelperSubprocessFailed.new(
message: "No space left on device",
error_class: "Dependabot::OutOfDisk",
error_context: error_context
)
elsif stderr&.include?("MemoryError")
raise HelperSubprocessFailed.new(
message: "MemoryError",
error_class: "Dependabot::OutOfMemory",
error_context: error_context
)
end
end

sig { params(command: String, stdin_data: String, env: T.nilable(T::Hash[String, String])).returns(String) }
def self.helper_subprocess_bash_command(command:, stdin_data:, env:)
escaped_stdin_data = stdin_data.gsub("\"", "\\\"")
Expand Down
20 changes: 20 additions & 0 deletions common/spec/dependabot/shared_helpers_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,26 @@ def existing_tmp_folders
.to raise_error(Dependabot::SharedHelpers::HelperSubprocessFailed)
end
end

context "when the subprocess exits with out of disk error" do
let(:command) { File.join(spec_root, "helpers/test/error_bash disk") }
it "raises a HelperSubprocessFailed out of disk error" do
expect { run_shell_command }
.to raise_error(Dependabot::SharedHelpers::HelperSubprocessFailed) do |error|
expect(error.message).to include("No space left on device")
end
end

context "when the subprocess exits with out of memory error" do
let(:command) { File.join(spec_root, "helpers/test/error_bash memory") }
it "raises a HelperSubprocessFailed out of memory error" do
expect { run_shell_command }
.to raise_error(Dependabot::SharedHelpers::HelperSubprocessFailed) do |error|
expect(error.message).to include("MemoryError")
end
end
end
end
end

describe ".escape_command" do
Expand Down
6 changes: 6 additions & 0 deletions common/spec/helpers/test/error_bash
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,10 @@

set -e

if [ "$1" = "disk" ]; then
echo "No space left on device" >&2
elif [ "$1" = "memory" ]; then
echo "MemoryError" >&2
fi

exit 1
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ class GoModUpdater

OUT_OF_DISK_REGEXES = [
%r{input/output error},
/no space left on device/
/no space left on device/,
/Out of diskspace/
].freeze

GO_MOD_VERSION = /^go 1\.\d+(\.\d+)?$/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -962,6 +962,17 @@
expect(error.message).to include("info/attributes: no space left on device")
end
end

it "detects 'Out of diskspace'" do
stderr = <<~ERROR
rsc.io/sampler imports
write fatal: sha1 file '/home/dependabot/dependabot-updater/repo/.git/index.lock' write error. Out of diskspace
ERROR

expect { updater.send(:handle_subprocess_error, stderr) }.to raise_error(Dependabot::OutOfDisk) do |error|
expect(error.message).to include("write error. Out of diskspace")
end
end
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ def parsed
function: "yarn:parseLockfile",
args: [Dir.pwd]
)
rescue SharedHelpers::HelperSubprocessFailed
rescue SharedHelpers::HelperSubprocessFailed => e
raise Dependabot::OutOfDisk, e.message if e.message.end_with?("No space left on device")
raise Dependabot::OutOfDisk, e.message if e.message.end_with?("Out of diskspace")
raise Dependabot::OutOfMemory, e.message if e.message.end_with?("MemoryError")

raise Dependabot::DependencyFileNotParseable, @dependency_file.path
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,46 @@
end
end
end

context "that contain out of disk/memory error" do
let(:dependency_files) { project_dependency_files("yarn/broken_lockfile") }

context "because it ran out of disk space" do
before do
allow(Dependabot::SharedHelpers)
.to receive(:run_helper_subprocess)
.and_raise(
Dependabot::SharedHelpers::HelperSubprocessFailed.new(
message: "No space left on device",
error_context: {}
)
)
end

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

context "because it ran out of memory" do
before do
allow(Dependabot::SharedHelpers)
.to receive(:run_helper_subprocess)
.and_raise(
Dependabot::SharedHelpers::HelperSubprocessFailed.new(
message: "MemoryError",
error_context: {}
)
)
end

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

context "for pnpm lockfiles" do
Expand Down

0 comments on commit c676f59

Please sign in to comment.