diff --git a/src/Illuminate/Process/Exceptions/ProcessFailedException.php b/src/Illuminate/Process/Exceptions/ProcessFailedException.php index 227ef29d0cca..6747c11867b3 100644 --- a/src/Illuminate/Process/Exceptions/ProcessFailedException.php +++ b/src/Illuminate/Process/Exceptions/ProcessFailedException.php @@ -3,7 +3,7 @@ namespace Illuminate\Process\Exceptions; use Illuminate\Contracts\Process\ProcessResult; -use Symfony\Component\Console\Exception\RuntimeException; +use RuntimeException; class ProcessFailedException extends RuntimeException { @@ -24,9 +24,19 @@ public function __construct(ProcessResult $result) { $this->result = $result; - parent::__construct( - sprintf('The process "%s" failed.', $result->command()), - $result->exitCode() ?? 1, + $error = sprintf('The command "%s" failed.'."\n\nExit Code: %s", + $result->command(), + $result->exitCode(), ); + + if (! empty($result->output())) { + $error .= sprintf("\n\nOutput:\n================\n%s", $result->output()); + } + + if (! empty($result->errorOutput())) { + $error .= sprintf("\n\nError Output:\n================\n%s", $result->errorOutput()); + } + + parent::__construct($error, $result->exitCode() ?? 1); } } diff --git a/tests/Process/ProcessTest.php b/tests/Process/ProcessTest.php index f0fd7dd34291..6a1eac5bd766 100644 --- a/tests/Process/ProcessTest.php +++ b/tests/Process/ProcessTest.php @@ -424,14 +424,81 @@ public function testRealProcessesCanHaveErrorOutput() $this->assertEquals("Hello World\n", $result->errorOutput()); } - public function testRealProcessesCanThrow() + public function testFakeProcessesCanThrowWithoutOutput() + { + $this->expectException(ProcessFailedException::class); + $this->expectExceptionMessage(<<<'EOT' + The command "exit 1;" failed. + + Exit Code: 1 + EOT + ); + + $factory = new Factory; + $factory->fake(fn () => $factory->result(exitCode: 1)); + $result = $factory->path(__DIR__)->run('exit 1;'); + + $result->throw(); + } + + public function testRealProcessesCanThrowWithoutOutput() + { + if (windows_os()) { + $this->markTestSkipped('Requires Linux.'); + } + + $this->expectException(ProcessFailedException::class); + $this->expectExceptionMessage(<<<'EOT' + The command "exit 1;" failed. + + Exit Code: 1 + EOT + ); + + $factory = new Factory; + $result = $factory->path(__DIR__)->run('exit 1;'); + + $result->throw(); + } + + public function testFakeProcessesCanThrowWithErrorOutput() + { + $this->expectException(ProcessFailedException::class); + $this->expectExceptionMessage(<<<'EOT' + The command "echo "Hello World" >&2; exit 1;" failed. + + Exit Code: 1 + + Error Output: + ================ + Hello World + EOT + ); + + $factory = new Factory; + $factory->fake(fn () => $factory->result(errorOutput: 'Hello World', exitCode: 1)); + $result = $factory->path(__DIR__)->run('echo "Hello World" >&2; exit 1;'); + + $result->throw(); + } + + public function testRealProcessesCanThrowWithErrorOutput() { if (windows_os()) { $this->markTestSkipped('Requires Linux.'); } $this->expectException(ProcessFailedException::class); - $this->expectExceptionMessage('The process "echo "Hello World" >&2; exit 1;" failed.'); + $this->expectExceptionMessage(<<<'EOT' + The command "echo "Hello World" >&2; exit 1;" failed. + + Exit Code: 1 + + Error Output: + ================ + Hello World + EOT + ); $factory = new Factory; $result = $factory->path(__DIR__)->run('echo "Hello World" >&2; exit 1;'); @@ -439,6 +506,51 @@ public function testRealProcessesCanThrow() $result->throw(); } + public function testFakeProcessesCanThrowWithOutput() + { + $this->expectException(ProcessFailedException::class); + $this->expectExceptionMessage(<<<'EOT' + The command "echo "Hello World" >&1; exit 1;" failed. + + Exit Code: 1 + + Output: + ================ + Hello World + EOT + ); + + $factory = new Factory; + $factory->fake(fn () => $factory->result(output: 'Hello World', exitCode: 1)); + $result = $factory->path(__DIR__)->run('echo "Hello World" >&1; exit 1;'); + + $result->throw(); + } + + public function testRealProcessesCanThrowWithOutput() + { + if (windows_os()) { + $this->markTestSkipped('Requires Linux.'); + } + + $this->expectException(ProcessFailedException::class); + $this->expectExceptionMessage(<<<'EOT' + The command "echo "Hello World" >&1; exit 1;" failed. + + Exit Code: 1 + + Output: + ================ + Hello World + EOT + ); + + $factory = new Factory; + $result = $factory->path(__DIR__)->run('echo "Hello World" >&1; exit 1;'); + + $result->throw(); + } + public function testRealProcessesCanTimeout() { if (windows_os()) {