Skip to content

Commit c6222fe

Browse files
author
ryan.kelley
committed
Make fail_loud apply to renderer exceptions
1 parent 295e0c1 commit c6222fe

File tree

3 files changed

+114
-21
lines changed

3 files changed

+114
-21
lines changed

src/Limenius/ReactRenderer/Renderer/ExternalServerReactRenderer.php

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Limenius\ReactRenderer\Context\ContextProviderInterface;
66
use Psr\Log\LoggerInterface;
7+
use Psr\Log\LogLevel;
78

89
/**
910
* Class ExternalServerReactRenderer
@@ -55,23 +56,43 @@ public function setServerSocketPath($serverSocketPath)
5556
*/
5657
public function render($componentName, $propsString, $uuid, $registeredStores = array(), $trace)
5758
{
58-
if (strpos($this->serverSocketPath, '://') === false) {
59-
$this->serverSocketPath = 'unix://'.$this->serverSocketPath;
60-
}
59+
try {
60+
if (\strpos($this->serverSocketPath, '://') === false) {
61+
$this->serverSocketPath = 'unix://'.$this->serverSocketPath;
62+
}
6163

62-
if (!$sock = stream_socket_client($this->serverSocketPath, $errno, $errstr)) {
63-
throw new \RuntimeException($errstr);
64-
}
65-
stream_socket_sendto($sock, $this->wrap($componentName, $propsString, $uuid, $registeredStores, $trace)."\0");
64+
if (!$sock = \stream_socket_client($this->serverSocketPath, $errno, $errstr)) {
65+
throw new \RuntimeException($errstr);
66+
}
67+
\stream_socket_sendto(
68+
$sock,
69+
$this->wrap($componentName, $propsString, $uuid, $registeredStores, $trace)."\0"
70+
);
71+
72+
$contents = '';
6673

67-
$contents = '';
74+
while (!\feof($sock)) {
75+
$contents .= \fread($sock, 8192);
76+
}
77+
\fclose($sock);
78+
79+
$result = \json_decode($contents, true);
80+
} catch (\Throwable $t) {
81+
if ($this->failLoud) {
82+
throw $t;
83+
}
84+
85+
if ($this->logger) {
86+
$this->logger->log(LogLevel::ERROR, $t->getMessage(), ['exception' => $t]);
87+
}
6888

69-
while (!feof($sock)) {
70-
$contents .= fread($sock, 8192);
89+
return [
90+
'evaluated' => '',
91+
'consoleReplay' => '',
92+
'hasErrors' => true,
93+
];
7194
}
72-
fclose($sock);
7395

74-
$result = json_decode($contents, true);
7596
if ($result['hasErrors']) {
7697
$this->logErrors($result['consoleReplayScript']);
7798
if ($this->failLoud) {

src/Limenius/ReactRenderer/Renderer/PhpExecJsReactRenderer.php

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22

33
namespace Limenius\ReactRenderer\Renderer;
44

5-
use Nacmartin\PhpExecJs\PhpExecJs;
6-
use Psr\Log\LoggerInterface;
75
use Limenius\ReactRenderer\Context\ContextProviderInterface;
6+
use Nacmartin\PhpExecJs\PhpExecJs;
87
use Psr\Cache\CacheItemPoolInterface;
8+
use Psr\Log\LoggerInterface;
9+
use Psr\Log\LogLevel;
910

1011
/**
1112
* Class PhpExecJsReactRenderer
@@ -93,15 +94,38 @@ public function setServerBundlePath($serverBundlePath)
9394
*/
9495
public function render($componentName, $propsString, $uuid, $registeredStores = array(), $trace)
9596
{
96-
$this->ensurePhpExecJsIsBuilt();
97-
if ($this->needToSetContext) {
98-
if ($this->phpExecJs->supportsCache()) {
99-
$this->phpExecJs->setCache($this->cache);
97+
try {
98+
$this->ensurePhpExecJsIsBuilt();
99+
if ($this->needToSetContext) {
100+
if ($this->phpExecJs->supportsCache()) {
101+
$this->phpExecJs->setCache($this->cache);
102+
}
103+
$this->phpExecJs->createContext(
104+
$this->consolePolyfill()."\n".$this->timerPolyfills($trace)."\n".$this->loadServerBundle(),
105+
$this->cacheKey
106+
);
107+
$this->needToSetContext = false;
108+
}
109+
$result = \json_decode(
110+
$this->phpExecJs->evalJs($this->wrap($componentName, $propsString, $uuid, $registeredStores, $trace)),
111+
true
112+
);
113+
} catch (\Throwable $t) {
114+
if ($this->failLoud) {
115+
throw $t;
116+
}
117+
118+
if ($this->logger) {
119+
$this->logger->log(LogLevel::ERROR, $t->getMessage(), ['exception' => $t]);
100120
}
101-
$this->phpExecJs->createContext($this->consolePolyfill()."\n".$this->timerPolyfills($trace)."\n".$this->loadServerBundle(), $this->cacheKey);
102-
$this->needToSetContext = false;
121+
122+
return [
123+
'evaluated' => '',
124+
'consoleReplay' => '',
125+
'hasErrors' => true,
126+
];
103127
}
104-
$result = json_decode($this->phpExecJs->evalJs($this->wrap($componentName, $propsString, $uuid, $registeredStores, $trace)), true);
128+
105129
if ($result['hasErrors']) {
106130
$this->logErrors($result['consoleReplayScript']);
107131
if ($this->failLoud) {

tests/Limenius/ReactRenderer/Tests/Renderer/PhpExecJsReactRendererTest.php

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Psr\Log\LoggerInterface;
88
use Nacmartin\PhpExecJs\PhpExecJs;
99
use PHPUnit\Framework\TestCase;
10+
use Psr\Log\LogLevel;
1011

1112
/**
1213
* Class PhpExecJsReactRendererTest
@@ -121,4 +122,51 @@ public function testFailLoud()
121122
$this->renderer->setPhpExecJs($phpExecJs);
122123
$this->renderer->render('MyApp', 'props', 1, null, true);
123124
}
125+
126+
/**
127+
* @testdox failLoud true bubbles thrown exceptions
128+
*/
129+
public function testFailLoudBubblesThrownException()
130+
{
131+
$err = new \Exception('test exception');
132+
$this->phpExecJs->method('createContext')->willThrowException($err);
133+
$this->renderer = new PhpExecJsReactRenderer(__DIR__.'/Fixtures/server-bundle.js', true, $this->contextProvider, $this->logger);
134+
$this->renderer->setPhpExecJs($this->phpExecJs);
135+
136+
$this->expectExceptionObject($err);
137+
$this->renderer->render('MyApp', 'props', 1, null, true);
138+
}
139+
140+
/**
141+
* @testdox failLoud false returns empty error result on exception
142+
*/
143+
public function testFailQuietReturnsEmptyErrorResultOnException()
144+
{
145+
$this->phpExecJs->method('createContext')->willThrowException(new \Exception('test exception'));
146+
147+
$this->assertEquals(
148+
[
149+
'evaluated' => '',
150+
'consoleReplay' => '',
151+
'hasErrors' => true,
152+
],
153+
$this->renderer->render('MyApp', 'props', 1, null, true)
154+
);
155+
}
156+
157+
/**
158+
* @testdox failLoud false logs thrown exceptions
159+
*/
160+
public function testFailQuietLogsThrownExceptions()
161+
{
162+
$err = new \Exception('test exception');
163+
$this->phpExecJs->method('createContext')->willThrowException($err);
164+
165+
$this->logger
166+
->expects($this->exactly(1))
167+
->method('log')
168+
->with(LogLevel::ERROR, 'test exception', ['exception' => $err]);
169+
170+
$this->renderer->render('MyApp', 'props', 1, null, true);
171+
}
124172
}

0 commit comments

Comments
 (0)