Skip to content

Commit 4ae0510

Browse files
ENGCOM-6919: Ui: log exception correctly #25426
2 parents 403bc3b + fe59d68 commit 4ae0510

File tree

2 files changed

+163
-8
lines changed

2 files changed

+163
-8
lines changed

app/code/Magento/Ui/TemplateEngine/Xhtml/Result.php

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55
*/
66
namespace Magento\Ui\TemplateEngine\Xhtml;
77

8-
use Magento\Framework\App\ObjectManager;
8+
use Magento\Framework\App\State;
99
use Magento\Framework\Serialize\Serializer\JsonHexTag;
10-
use Magento\Framework\View\Layout\Generator\Structure;
1110
use Magento\Framework\View\Element\UiComponentInterface;
12-
use Magento\Framework\View\TemplateEngine\Xhtml\Template;
13-
use Magento\Framework\View\TemplateEngine\Xhtml\ResultInterface;
11+
use Magento\Framework\View\Layout\Generator\Structure;
1412
use Magento\Framework\View\TemplateEngine\Xhtml\CompilerInterface;
13+
use Magento\Framework\View\TemplateEngine\Xhtml\ResultInterface;
14+
use Magento\Framework\View\TemplateEngine\Xhtml\Template;
1515
use Psr\Log\LoggerInterface;
1616

1717
/**
18-
* Class Result
18+
* Convert DOMElement to string representation
1919
*/
2020
class Result implements ResultInterface
2121
{
@@ -49,28 +49,36 @@ class Result implements ResultInterface
4949
*/
5050
private $jsonSerializer;
5151

52+
/**
53+
* @var State
54+
*/
55+
private $state;
56+
5257
/**
5358
* @param Template $template
5459
* @param CompilerInterface $compiler
5560
* @param UiComponentInterface $component
5661
* @param Structure $structure
5762
* @param LoggerInterface $logger
5863
* @param JsonHexTag $jsonSerializer
64+
* @param State $state
5965
*/
6066
public function __construct(
6167
Template $template,
6268
CompilerInterface $compiler,
6369
UiComponentInterface $component,
6470
Structure $structure,
6571
LoggerInterface $logger,
66-
JsonHexTag $jsonSerializer = null
72+
JsonHexTag $jsonSerializer,
73+
State $state
6774
) {
6875
$this->template = $template;
6976
$this->compiler = $compiler;
7077
$this->component = $component;
7178
$this->structure = $structure;
7279
$this->logger = $logger;
73-
$this->jsonSerializer = $jsonSerializer ?? ObjectManager::getInstance()->get(JsonHexTag::class);
80+
$this->jsonSerializer = $jsonSerializer;
81+
$this->state = $state;
7482
}
7583

7684
/**
@@ -116,8 +124,11 @@ public function __toString()
116124
$this->appendLayoutConfiguration();
117125
$result = $this->compiler->postprocessing($this->template->__toString());
118126
} catch (\Throwable $e) {
119-
$this->logger->critical($e->getMessage());
127+
$this->logger->critical($e);
120128
$result = $e->getMessage();
129+
if ($this->state->getMode() === State::MODE_DEVELOPER) {
130+
$result .= "<pre><code>Exception in {$e->getFile()}:{$e->getLine()}</code></pre>";
131+
}
121132
}
122133
return $result;
123134
}
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
declare(strict_types=1);
8+
9+
namespace Magento\Ui\Test\Unit\TemplateEngine\Xhtml;
10+
11+
use Magento\Framework\App\State;
12+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager as ObjectManagerHelper;
13+
use Magento\Framework\View\Element\UiComponentInterface;
14+
use Magento\Framework\View\TemplateEngine\Xhtml\CompilerInterface;
15+
use Magento\Framework\View\TemplateEngine\Xhtml\Template;
16+
use Magento\Ui\Component\Listing;
17+
use Magento\Ui\TemplateEngine\Xhtml\Result;
18+
use PHPUnit\Framework\MockObject\MockObject;
19+
use PHPUnit\Framework\TestCase;
20+
use Psr\Log\LoggerInterface;
21+
22+
/**
23+
* Test for \Magento\Ui\TemplateEngine\Xhtml\Result.
24+
*/
25+
class ResultTest extends TestCase
26+
{
27+
/**
28+
* Stub simple html element
29+
*/
30+
private const STUB_HTML_ELEMENT = '<div id="id"></div>';
31+
32+
/**
33+
* @var Result
34+
*/
35+
private $model;
36+
37+
/**
38+
* @var ObjectManagerHelper|MockObject
39+
*/
40+
private $objectManagerHelper;
41+
42+
/**
43+
* @var Template|MockObject
44+
*/
45+
private $templateMock;
46+
47+
/**
48+
* @var CompilerInterface|MockObject
49+
*/
50+
private $compilerMock;
51+
52+
/**
53+
* @var UiComponentInterface|MockObject
54+
*/
55+
private $componentMock;
56+
57+
/**
58+
* @var LoggerInterface|MockObject
59+
*/
60+
private $loggerMock;
61+
62+
/**
63+
* @var State|MockObject
64+
*/
65+
private $stateMock;
66+
67+
/**
68+
* @inheritdoc
69+
*/
70+
protected function setUp()
71+
{
72+
$this->templateMock = $this->createMock(Template::class);
73+
$this->compilerMock = $this->createMock(CompilerInterface::class);
74+
$this->componentMock = $this->createMock(Listing::class);
75+
$this->loggerMock = $this->createMock(LoggerInterface::class);
76+
$this->stateMock = $this->createMock(State::class);
77+
78+
$this->objectManagerHelper = new ObjectManagerHelper($this);
79+
$this->model = $this->objectManagerHelper->getObject(
80+
Result::class,
81+
[
82+
'template' => $this->templateMock,
83+
'compiler' => $this->compilerMock,
84+
'component' => $this->componentMock,
85+
'logger' => $this->loggerMock,
86+
'state' => $this->stateMock,
87+
]
88+
);
89+
}
90+
91+
/**
92+
* To string method with exception message
93+
*
94+
* @return void
95+
*/
96+
public function testToStringWithException(): void
97+
{
98+
$e = new \Exception();
99+
100+
$this->templateMock->expects($this->once())
101+
->method('getDocumentElement')
102+
->willThrowException($e);
103+
$this->stateMock->expects($this->once())
104+
->method('getMode')
105+
->willReturn(State::MODE_DEVELOPER);
106+
107+
$this->loggerMock->expects($this->once())
108+
->method('critical')
109+
->with($e);
110+
$this->assertEquals(
111+
'<pre><code>Exception in ' . $e->getFile() . ':' . $e->getLine() . '</code></pre>',
112+
$this->model->__toString()
113+
);
114+
}
115+
116+
/**
117+
* To string method
118+
*
119+
* @return void
120+
*/
121+
public function testToString(): void
122+
{
123+
$domElementMock = $this->getMockBuilder(\DOMElement::class)
124+
->setConstructorArgs(['arg'])
125+
->getMock();
126+
127+
$this->templateMock->expects($this->once())
128+
->method('getDocumentElement')
129+
->willReturn($domElementMock);
130+
$this->compilerMock->expects($this->once())
131+
->method('compile')
132+
->with(
133+
$this->isInstanceOf(\DOMElement::class),
134+
$this->componentMock,
135+
$this->componentMock
136+
);
137+
$this->templateMock->expects($this->once())->method('__toString');
138+
$this->compilerMock->expects($this->once())
139+
->method('postprocessing')
140+
->willReturn(self::STUB_HTML_ELEMENT);
141+
142+
$this->assertEquals(self::STUB_HTML_ELEMENT, $this->model->__toString());
143+
}
144+
}

0 commit comments

Comments
 (0)