8000 Merge pull request #73 from clue-labs/error-reporting · reactphp/child-process@1409327 · GitHub
[go: up one dir, main page]

Skip to content

Commit 1409327

Browse files
authored
Merge pull request #73 from clue-labs/error-reporting
Improve error reporting when spawning child process fails
2 parents 1106c24 + 1e61ce4 commit 1409327

File tree

2 files changed

+53
-2
lines changed

2 files changed

+53
-2
lines changed

src/Process.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,11 @@ public function start(LoopInterface $loop, $interval = 0.1)
189189
$options['suppress_errors'] = true;
190190
}
191191

192-
$this->process = \proc_open($cmd, $fdSpec, $pipes, $this->cwd, $this->env, $options);
192+
$this->process = @\proc_open($cmd, $fdSpec, $pipes, $this->cwd, $this->env, $options);
193193

194194
if (!\is_resource($this->process)) {
195-
throw new \RuntimeException('Unable to launch a new process.');
195+
$error = \error_get_last();
196+
throw new \RuntimeException('Unable to launch a new process: ' . $error['message']);
196197
}
197198

198199
// count open process pipes and await close event for each to drain buffers before detecting exit

tests/AbstractProcessTest.php

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,56 @@ public function testStartWithCustomPipesWillAssignPipes()
8484
$this->assertInstanceOf('React\Stream\WritableStreamInterface', $process->pipes[3]);
8585
}
8686

87+
/**
88+
* @expectedException RuntimeException
89+
* @expectedExceptionMessage No such file or directory
90+
*/
91+
public function testStartWithInvalidFileDescriptorPathWillThrow()
92+
{
93+
$fds = array(
94+
4 => array('file', '/dev/does-not-exist', 'r')
95+
);
96+
97+
$process = new Process('exit 0', null, null, $fds);
98+
$process->start($this->createLoop());
99+
}
100+
101+
public function testStartWithExcessiveNumberOfFileDescriptorsWillThrow()
102+
{
103+
if (PHP_VERSION_ID < 70000) {
104+
$this->markTestSkipped('PHP 7+ only, causes memory overflow on legacy PHP 5');
105+
}
106+
107+
$ulimit = exec('ulimit -n 2>&1');
108+
if ($ulimit < 1) {
109+
$this->markTestSkipped('Unable to determine limit of open files (ulimit not available?)');
110+
}
111+
112+
$loop = $this->createLoop();
113+
114+
// create 70% (usually ~700) dummy file handles in this parent dummy
115+
$limit = (int)($ulimit * 0.7);
116+
$fds = array();
117+
for ($i = 0; $i < $limit; ++$i) {
118+
$fds[$i] = fopen('/dev/null', 'r');
119+
}
120+
121+
// try to create child process with another ~700 dummy file handles
122+
$new = array_fill(0, $limit, array('file', '/dev/null', 'r'));
123+
$process = new Process('ping example.com', null, null, $new);
124+
125+
try {
126+
$process->start($loop);
127+
128+
$this->fail('Did not expect to reach this point');
129+
} catch (\RuntimeException $e) {
130+
// clear dummy files handles to make some room again (avoid fatal errors for autoloader)
131+
$fds = array();
132+
133+
$this->assertContains('Too many open files', $e->getMessage());
134+
}
135+
}
136+
87137
public function testIsRunning()
88138
{
89139
if (DIRECTORY_SEPARATOR === '\\') {

0 commit comments

Comments
 (0)
0