Skip to content

Commit dfd481d

Browse files
committed
#24043: Better exception handling during cli commands.
1 parent 71b0142 commit dfd481d

File tree

2 files changed

+91
-1
lines changed

2 files changed

+91
-1
lines changed

lib/internal/Magento/Framework/Console/Cli.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Magento\Setup\Application;
2020
use Magento\Setup\Console\CompilerPreparation;
2121
use Magento\Setup\Model\ObjectManagerProvider;
22+
use Psr\Log\LoggerInterface;
2223
use Symfony\Component\Console;
2324
use Magento\Framework\Config\ConfigOptionsListConstants;
2425

@@ -61,6 +62,11 @@ class Cli extends Console\Application
6162
*/
6263
private $objectManager;
6364

65+
/**
66+
* @var LoggerInterface
67+
*/
68+
private $logger;
69+
6470
/**
6571
* @param string $name the application name
6672
* @param string $version the application version
@@ -94,6 +100,7 @@ public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN')
94100

95101
parent::__construct($name, $version);
96102
$this->serviceManager->setService(\Symfony\Component\Console\Application::class, $this);
103+
$this->logger = $this->objectManager->get(LoggerInterface::class);
97104
}
98105

99106
/**
@@ -107,7 +114,9 @@ public function doRun(Console\Input\InputInterface $input, Console\Output\Output
107114
try {
108115
$exitCode = parent::doRun($input, $output);
109116
} catch (\Exception $e) {
110-
$output->writeln($e->getTraceAsString());
117+
$errorMessage = $e->getMessage() . PHP_EOL . $e->getTraceAsString();
118+
$this->logger->error($errorMessage);
119+
$this->initException = $e;
111120
}
112121

113122
if ($this->initException) {
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Framework\Console\Test\Unit;
9+
10+
use Magento\Framework\Console\Cli;
11+
use PHPUnit\Framework\MockObject\MockObject;
12+
use Psr\Log\LoggerInterface;
13+
use Symfony\Component\Console\Input\InputInterface;
14+
use Symfony\Component\Console\Output\OutputInterface;
15+
16+
/**
17+
* Test for Magento\Framework\Console\Cli class.
18+
*/
19+
class CliTest extends \PHPUnit\Framework\TestCase
20+
{
21+
/**
22+
* @var Cli
23+
*/
24+
private $cli;
25+
26+
/**
27+
* @var InputInterface|MockObject
28+
*/
29+
private $inputMock;
30+
31+
/**
32+
* @var OutputInterface|MockObject
33+
*/
34+
private $outputMock;
35+
36+
/**
37+
* @inheritdoc
38+
*/
39+
protected function setUp()
40+
{
41+
$this->inputMock = $this->getMockBuilder(InputInterface::class)
42+
->getMockForAbstractClass();
43+
$this->outputMock = $this->getMockBuilder(OutputInterface::class)
44+
->getMockForAbstractClass();
45+
$this->cli = new Cli();
46+
}
47+
48+
/**
49+
* Make sure exception message is displayed and trace is logged.
50+
*
51+
* @expectedException \Exception
52+
* @expectedExceptionMessage Test message
53+
*/
54+
public function testDoRunExceptionLogging()
55+
{
56+
$e = new \Exception('Test message');
57+
$this->inputMock->expects($this->once())->method('getFirstArgument')->willThrowException($e);
58+
$loggerMock = $this->createMock(LoggerInterface::class);
59+
$loggerMock->expects($this->once())
60+
->method('error')
61+
->with($e->getMessage() . PHP_EOL . $e->getTraceAsString());
62+
$this->injectMock($loggerMock, 'logger');
63+
64+
$this->cli->doRun($this->inputMock, $this->outputMock);
65+
}
66+
67+
/**
68+
* Inject mock to Cli property.
69+
*
70+
* @param MockObject $mockObject
71+
* @param string $propertyName
72+
* @throws \ReflectionException
73+
*/
74+
private function injectMock(MockObject $mockObject, string $propertyName): void
75+
{
76+
$reflection = new \ReflectionClass(Cli::class);
77+
$reflectionProperty = $reflection->getProperty($propertyName);
78+
$reflectionProperty->setAccessible(true);
79+
$reflectionProperty->setValue($this->cli, $mockObject);
80+
}
81+
}

0 commit comments

Comments
 (0)