From 5a5b6f7d4ada5ffbf55821499c547d182f8509c1 Mon Sep 17 00:00:00 2001 From: Pawel Siejba Date: Fri, 23 Oct 2020 16:30:49 +0200 Subject: [PATCH] Handle exceptions thrown in child processes forked by ProcessManager, instead of handling them in the parent process execution flow --- .../Magento/Indexer/Model/ProcessManager.php | 34 +++++++++++++++---- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/app/code/Magento/Indexer/Model/ProcessManager.php b/app/code/Magento/Indexer/Model/ProcessManager.php index 2f2c500e028cf..2b25c8c6a3d15 100644 --- a/app/code/Magento/Indexer/Model/ProcessManager.php +++ b/app/code/Magento/Indexer/Model/ProcessManager.php @@ -7,6 +7,9 @@ namespace Magento\Indexer\Model; +use Magento\Framework\App\ObjectManager; +use Psr\Log\LoggerInterface; + /** * Provide functionality for executing user functions in multi-thread mode. */ @@ -29,15 +32,22 @@ class ProcessManager /** @var int|null */ private $threadsCount; + /** + * @var LoggerInterface + */ + private $logger; + /** * @param \Magento\Framework\App\ResourceConnection $resource * @param \Magento\Framework\Registry $registry * @param int|null $threadsCount + * @param LoggerInterface|null $logger */ public function __construct( \Magento\Framework\App\ResourceConnection $resource, \Magento\Framework\Registry $registry = null, - int $threadsCount = null + int $threadsCount = null, + LoggerInterface $logger = null ) { $this->resource = $resource; if (null === $registry) { @@ -47,6 +57,9 @@ public function __construct( } $this->registry = $registry; $this->threadsCount = (int)$threadsCount; + $this->logger = $logger ?? ObjectManager::getInstance()->get( + LoggerInterface::class + ); } /** @@ -135,11 +148,20 @@ private function isSetupMode(): bool */ private function startChildProcess(callable $userFunction) { - // phpcs:ignore Magento2.Functions.DiscouragedFunction - $status = call_user_func($userFunction); - $status = is_int($status) ? $status : 0; - // phpcs:ignore Magento2.Security.LanguageConstruct.ExitUsage - exit($status); + try { + // phpcs:ignore Magento2.Functions.DiscouragedFunction + $status = call_user_func($userFunction); + $status = is_int($status) ? $status : 0; + } catch (\Throwable $e) { + $status = 1; + $this->logger->error( + __('Child process failed with message: %1', $e->getMessage()), + ['exception' => $e] + ); + } finally { + // phpcs:ignore Magento2.Security.LanguageConstruct.ExitUsage + exit($status); + } } /**