diff --git a/src/Console/Command/WorkerCommand.php b/src/Console/Command/WorkerCommand.php index 1ee177fd18c..26b6e62dae1 100644 --- a/src/Console/Command/WorkerCommand.php +++ b/src/Console/Command/WorkerCommand.php @@ -18,7 +18,6 @@ use Clue\React\NDJson\Encoder; use PhpCsFixer\Config; use PhpCsFixer\Console\ConfigurationResolver; -use PhpCsFixer\Error\Error; use PhpCsFixer\Error\ErrorsManager; use PhpCsFixer\FixerFileProcessedEvent; use PhpCsFixer\Runner\Parallel\ParallelConfig; @@ -177,14 +176,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int ? $this->events[$i]->getStatus() : null; $result[$relativePath]['fixInfo'] = $analysisResult[$relativePath] ?? null; - // @TODO consider serialising whole Error, so it can be deserialised on server side and passed to error manager - $result[$relativePath]['errors'] = array_map( - static fn (Error $error): array => [ - 'type' => $error->getType(), - 'error_message' => null !== $error->getSource() ? $error->getSource()->getMessage() : null, - ], - $this->errorsManager->forPath($absolutePath) - ); + $result[$relativePath]['errors'] = $this->errorsManager->forPath($absolutePath); } $out->write(['action' => 'result', 'result' => $result]); diff --git a/src/Error/Error.php b/src/Error/Error.php index 1f14ed9f0f1..06e95a5a324 100644 --- a/src/Error/Error.php +++ b/src/Error/Error.php @@ -21,7 +21,7 @@ * * @internal */ -final class Error +final class Error implements \JsonSerializable { /** * Error which has occurred in linting phase, before applying any fixers. @@ -38,6 +38,7 @@ final class Error */ public const TYPE_LINT = 3; + /** @var self::TYPE_* */ private int $type; private string $filePath; @@ -90,4 +91,31 @@ public function getDiff(): ?string { return $this->diff; } + + /** + * @return array{ + * type: self::TYPE_*, + * filePath: string, + * source: null|array{message: string, code: int, file: string, line: int}, + * appliedFixers: list, + * diff: null|string + * } + */ + public function jsonSerialize(): array + { + return [ + 'type' => $this->type, + 'filePath' => $this->filePath, + 'source' => null !== $this->source + ? [ + 'message' => $this->source->getMessage(), + 'code' => $this->source->getCode(), + 'file' => $this->source->getFile(), + 'line' => $this->source->getLine(), + ] + : null, + 'appliedFixers' => $this->appliedFixers, + 'diff' => $this->diff, + ]; + } } diff --git a/src/Runner/Parallel/ParallelisationException.php b/src/Runner/Parallel/ParallelisationException.php index 5460519dd62..28a4b8ab9b7 100644 --- a/src/Runner/Parallel/ParallelisationException.php +++ b/src/Runner/Parallel/ParallelisationException.php @@ -27,4 +27,16 @@ public static function forUnknownIdentifier(ProcessIdentifier $identifier): self { return new self('Unknown process identifier: '.(string) $identifier); } + + /** + * @param array{message: string, code: int, file: string, line: int} $error + */ + public static function forWorkerError(array $error): self + { + $exception = new self($error['message'], $error['code']); + $exception->file = $error['file']; + $exception->line = $error['line']; + + return $exception; + } } diff --git a/src/Runner/Runner.php b/src/Runner/Runner.php index 7876878a8e9..fe64bb95f1e 100644 --- a/src/Runner/Runner.php +++ b/src/Runner/Runner.php @@ -214,7 +214,19 @@ function (array $analysisResult) use ($processPool, $process, $identifier, $file // Dispatch an event for each file processed and dispatch its status (required for progress output) $this->dispatchEvent(FixerFileProcessedEvent::NAME, new FixerFileProcessedEvent($result['status'])); - // @TODO Pass reported errors to the error manager + foreach ($result['errors'] ?? [] as $workerError) { + $error = new Error( + $workerError['type'], + $workerError['filePath'], + null !== $workerError['source'] + ? ParallelisationException::forWorkerError($workerError['source']) + : null, + $workerError['appliedFixers'], + $workerError['diff'] + ); + + $this->errorsManager->report($error); + } } // Request another chunk of files, if still available