Skip to content

Commit 7fe1005

Browse files
authored
Merge pull request #10902 from danog/throw_on_scan_issues
Throw exception instead of silently logging issues occurred during scan
2 parents 8fcb6b4 + 83069ff commit 7fe1005

File tree

4 files changed

+28
-37
lines changed

4 files changed

+28
-37
lines changed

src/Psalm/Internal/Codebase/Analyzer.php

-4
Original file line numberDiff line numberDiff line change
@@ -511,10 +511,6 @@ static function (): void {
511511
$this->argument_map[$file_path] = $argument_map;
512512
}
513513
}
514-
515-
if ($pool->didHaveError()) {
516-
exit(1);
517-
}
518514
} else {
519515
$i = 0;
520516

src/Psalm/Internal/Codebase/Scanner.php

-4
Original file line numberDiff line numberDiff line change
@@ -417,10 +417,6 @@ function () {
417417
);
418418
}
419419
}
420-
421-
if ($pool->didHaveError()) {
422-
exit(1);
423-
}
424420
} else {
425421
$i = 0;
426422

src/Psalm/Internal/Fork/Pool.php

+24-28
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,6 @@ final class Pool
8080
/** @var resource[] */
8181
private array $read_streams = [];
8282

83-
private bool $did_have_error = false;
84-
8583
/** @var ?Closure(mixed): void */
8684
private ?Closure $task_done_closure = null;
8785

@@ -297,6 +295,20 @@ private static function streamForChild(array $sockets)
297295
return $for_write;
298296
}
299297

298+
private function killAllChildren(): void
299+
{
300+
foreach ($this->child_pid_list as $child_pid) {
301+
/**
302+
* SIGTERM does not exist on windows
303+
*
304+
* @psalm-suppress UnusedPsalmSuppress
305+
* @psalm-suppress UndefinedConstant
306+
* @psalm-suppress MixedArgument
307+
*/
308+
posix_kill($child_pid, SIGTERM);
309+
}
310+
}
311+
300312
/**
301313
* Read the results that each child process has serialized on their write streams.
302314
* The results are returned in an array, one for each worker. The order of the results
@@ -319,6 +331,7 @@ private function readResultsFromChildren(): array
319331
$content = array_fill_keys(array_keys($streams), '');
320332

321333
$terminationMessages = [];
334+
$done = [];
322335

323336
// Read the data off of all the stream.
324337
while (count($streams) > 0) {
@@ -361,34 +374,25 @@ private function readResultsFromChildren(): array
361374
if ($message instanceof ForkProcessDoneMessage) {
362375
$terminationMessages[] = $message->data;
363376
} elseif ($message instanceof ForkTaskDoneMessage) {
377+
$done[(int)$file] = true;
364378
if ($this->task_done_closure !== null) {
365379
($this->task_done_closure)($message->data);
366380
}
367381
} elseif ($message instanceof ForkProcessErrorMessage) {
368-
// Kill all children
369-
foreach ($this->child_pid_list as $child_pid) {
370-
/**
371-
* SIGTERM does not exist on windows
372-
*
373-
* @psalm-suppress UnusedPsalmSuppress
374-
* @psalm-suppress UndefinedConstant
375-
* @psalm-suppress MixedArgument
376-
*/
377-
posix_kill($child_pid, SIGTERM);
378-
}
382+
$this->killAllChildren();
379383
throw new Exception($message->message);
380384
} else {
381-
error_log('Child should return ForkMessage - response type=' . gettype($message));
382-
$this->did_have_error = true;
385+
$this->killAllChildren();
386+
throw new Exception('Child should return ForkMessage - response type=' . gettype($message));
383387
}
384388
}
385389
}
386390

387391
// If the stream has closed, stop trying to select on it.
388392
if (feof($file)) {
389-
if ($content[(int)$file] !== '') {
390-
error_log('Child did not send full message before closing the connection');
391-
$this->did_have_error = true;
393+
if ($content[(int)$file] !== '' || !isset($done[(int)$file])) {
394+
$this->killAllChildren();
395+
throw new Exception('Child did not send full message before closing the connection');
392396
}
393397

394398
fclose($file);
@@ -450,21 +454,13 @@ public function wait(): array
450454
* @psalm-suppress UndefinedConstant
451455
*/
452456
if ($term_sig !== SIGALRM) {
453-
$this->did_have_error = true;
454-
error_log("Child terminated with return code $return_code and signal $term_sig");
457+
$this->killAllChildren();
458+
throw new Exception("Child terminated with return code $return_code and signal $term_sig");
455459
}
456460
}
457461
}
458462
}
459463

460464
return $content;
461465
}
462-
463-
/**
464-
* Returns true if this had an error, e.g. due to memory limits or due to a child process crashing.
465-
*/
466-
public function didHaveError(): bool
467-
{
468-
return $this->did_have_error;
469-
}
470466
}

src/Psalm/Internal/Fork/PsalmRestarter.php

+4-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
use function array_filter;
88
use function array_merge;
99
use function array_splice;
10+
use function assert;
11+
use function count;
1012
use function extension_loaded;
1113
use function file_get_contents;
1214
use function file_put_contents;
@@ -125,7 +127,7 @@ private static function toBytes(string $value): int
125127
/**
126128
* No type hint to allow xdebug-handler v1 and v2 usage
127129
*
128-
* @param string[] $command
130+
* @param non-empty-list<string> $command
129131
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
130132
*/
131133
protected function restart($command): void
@@ -167,6 +169,7 @@ protected function restart($command): void
167169
0,
168170
$additional_options,
169171
);
172+
assert(count($command) > 1);
170173

171174
parent::restart($command);
172175
}

0 commit comments

Comments
 (0)