diff --git a/lib/App/Perlbrew/HTTP.pm b/lib/App/Perlbrew/HTTP.pm index e0a61689..7c69f9dd 100644 --- a/lib/App/Perlbrew/HTTP.pm +++ b/lib/App/Perlbrew/HTTP.pm @@ -101,7 +101,15 @@ sub http_download { } unless ($status == 0) { $path->unlink; - return "ERROR: Failed to execute the command\n\n\t$download_command\n\nReason:\n\n\t$?"; + if ($? == -1) { + return "ERROR: Failed to execute the command\n\n\t$download_command\n\nReason:\n\n\t$!"; + } + elsif ($? & 127) { + return "ERROR: The command died with signal " . ($? & 127) . "\n\n\t$download_command\n\n"; + } + else { + return "ERROR: The command finished with error\n\n\t$download_command\n\nReason:\n\n\t" . ($? >> 8); + } } return 0; } diff --git a/t/error-http_download-exec-error.t b/t/error-http_download-exec-error.t new file mode 100644 index 00000000..3970f545 --- /dev/null +++ b/t/error-http_download-exec-error.t @@ -0,0 +1,26 @@ +#!/usr/bin/env perl +use strict; +use warnings; + +use Test::More import => [ qw( done_testing like subtest ) ]; +use File::Temp qw( tempdir ); + +BEGIN { + *CORE::GLOBAL::system = sub { + return $? = -1 + }; +} + +use App::Perlbrew::Path; +use App::Perlbrew::HTTP qw(http_download); + +local $ENV{PERLBREW_ROOT} = $App::perlbrew::PERLBREW_ROOT = tempdir( CLEANUP => 1 ); + +subtest "The exit status code of curl", sub { + my $error = http_download( "https://example.com/whatever.tar.gz", + App::Perlbrew::Path->new($App::perlbrew::PERLBREW_ROOT)->child("whatever.tar.gz") ); + + like $error, qr/^ERROR: Failed to execute the command/; +}; + +done_testing; diff --git a/t/error-http_download-exit-nonzero.t b/t/error-http_download-exit-nonzero.t new file mode 100644 index 00000000..e5478c5a --- /dev/null +++ b/t/error-http_download-exit-nonzero.t @@ -0,0 +1,28 @@ +#!/usr/bin/env perl +use strict; +use warnings; + +use Test::More import => [ qw( done_testing like subtest ) ]; +use File::Temp qw( tempdir ); + +my $actual_status_code = 42; + +BEGIN { + *CORE::GLOBAL::system = sub { + return $? = $actual_status_code << 8; + }; +} + +use App::Perlbrew::Path; +use App::Perlbrew::HTTP qw(http_download); + +local $ENV{PERLBREW_ROOT} = $App::perlbrew::PERLBREW_ROOT = tempdir( CLEANUP => 1 ); + +subtest "The exit status code of curl", sub { + my $error = http_download( "https://example.com/whatever.tar.gz", + App::Perlbrew::Path->new($App::perlbrew::PERLBREW_ROOT)->child("whatever.tar.gz") ); + + like $error, qr/^ERROR .+ Reason .+ ${actual_status_code}/xs; +}; + +done_testing; diff --git a/t/error-http_download-param-validation.t b/t/error-http_download-param-validation.t new file mode 100644 index 00000000..8ea3509b --- /dev/null +++ b/t/error-http_download-param-validation.t @@ -0,0 +1,22 @@ +use strict; +use warnings; +use Test::More; +use Test::Exception; +use File::Temp qw(tempdir); +use IO::All; +use App::Perlbrew::HTTP qw(http_download); + +subtest "http_download: dies when when the download target already exists" => sub { + my $dir = tempdir( CLEANUP => 1 ); + my $output = "$dir/whatever"; + + io($output)->print("so"); + + my $error; + throws_ok { + $error = http_download( "https://install.perlbrew.pl", $output ); + } + qr(^ERROR: The download target < \Q$output\E > already exists\.$); +}; + +done_testing;