Skip to content

Commit a225707

Browse files
authored
Let exceptions to bubble (#4)
* Let exceptions to bubble * Test JsonEncodeException * Modify JsonEncodeException construction * Rename test methods * Assert exception data * Fix variable juggling
1 parent 8b535cb commit a225707

File tree

4 files changed

+94
-42
lines changed

4 files changed

+94
-42
lines changed

src/BroadcasttClient.php

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,26 @@
55
use Broadcastt\Exception\InvalidArgumentException;
66
use Broadcastt\Exception\InvalidChannelNameException;
77
use Broadcastt\Exception\InvalidDataException;
8+
use Broadcastt\Exception\InvalidHostException;
89
use Broadcastt\Exception\InvalidSocketIdException;
10+
use Broadcastt\Exception\JsonEncodeException;
911
use Broadcastt\Exception\TooManyChannelsException;
10-
use Broadcastt\Exception\InvalidHostException;
1112
use GuzzleHttp\Client;
1213
use GuzzleHttp\ClientInterface;
1314
use GuzzleHttp\Exception\GuzzleException;
1415
use GuzzleHttp\Psr7\Request;
15-
use GuzzleHttp\Psr7\Response;
16-
use function GuzzleHttp\Psr7\stream_for;
1716
use GuzzleHttp\Psr7\Uri;
1817
use Psr\Http\Message\RequestInterface;
18+
use Psr\Http\Message\ResponseInterface;
1919
use Psr\Http\Message\UriInterface;
2020
use Psr\Log\LoggerAwareInterface;
2121
use Psr\Log\LoggerAwareTrait;
2222
use Psr\Log\LogLevel;
23+
use function GuzzleHttp\Psr7\stream_for;
2324

2425
/**
2526
* Class BroadcasttClient
27+
*
2628
* @package Broadcastt
2729
*
2830
* @property-read int $appId Id of your application
@@ -74,7 +76,6 @@ class BroadcasttClient implements LoggerAwareInterface
7476
'timeout' => null,
7577
];
7678

77-
7879
/**
7980
* Initializes a new Broadcastt instance with key, secret and ID of an app.
8081
*
@@ -101,6 +102,7 @@ public function __construct($appId, $appKey, $appSecret, $appCluster = 'eu')
101102
* Clients can be instantiated from a URI. For example: "http://key:[email protected]/apps/{appId}"
102103
*
103104
* @param string|UriInterface $uri
105+
*
104106
* @return BroadcasttClient
105107
*/
106108
public static function fromUri($uri)
@@ -126,7 +128,7 @@ public static function fromUri($uri)
126128
throw new InvalidArgumentException('Secret part of user info is missing from URI');
127129
}
128130

129-
list($appKey, $appSecret) = $userInfo;
131+
[$appKey, $appSecret] = $userInfo;
130132

131133
$client = new BroadcasttClient($appId, $appKey, $appSecret);
132134
$client->scheme = $uri->getScheme();
@@ -233,7 +235,7 @@ private function buildRequest($domain, $path, $requestMethod = 'GET', $queryPara
233235
*
234236
* @param RequestInterface $request
235237
*
236-
* @return Response
238+
* @return ResponseInterface
237239
* @throws GuzzleException
238240
*/
239241
private function sendRequest($request)
@@ -275,6 +277,7 @@ private function buildUri()
275277
* Check if the status code indicates the request was successful.
276278
*
277279
* @param $status
280+
*
278281
* @return bool
279282
*/
280283
private function isSuccessStatusCode($status)
@@ -345,7 +348,8 @@ public static function httpBuildQuery($array)
345348
* @param bool $jsonEncoded [optional]
346349
*
347350
* @return bool
348-
* invalid
351+
* @throws GuzzleException
352+
* @throws JsonEncodeException on JSON encode failure.
349353
*/
350354
public function trigger($channels, $name, $data, $socketId = null, $jsonEncoded = false)
351355
{
@@ -356,33 +360,28 @@ public function trigger($channels, $name, $data, $socketId = null, $jsonEncoded
356360
$this->validateChannels($channels);
357361
$this->validateSocketId($socketId);
358362

363+
$jsonData = $data;
359364
if (!$jsonEncoded) {
360-
$data = json_encode($data);
365+
$jsonData = json_encode($data);
361366

362-
// json_encode might return false on failure
363-
if (!$data) {
364-
$this->log('Failed to perform json_encode on the the provided data: {error}', [
365-
'error' => $data,
366-
], LogLevel::ERROR);
367+
// json_encode returns false on failure
368+
if ($jsonData === false) {
369+
throw new JsonEncodeException($data, json_last_error_msg(), json_last_error());
367370
}
368371
}
369372

370373
$postParams = [];
371374
$postParams['name'] = $name;
372-
$postParams['data'] = $data;
375+
$postParams['data'] = $jsonData;
373376
$postParams['channels'] = $channels;
374377

375378
if ($socketId !== null) {
376379
$postParams['socket_id'] = $socketId;
377380
}
378381

379-
try {
380-
$response = $this->post('/event', [], $postParams);
382+
$response = $this->post('/event', [], $postParams);
381383

382-
return $this->isSuccessStatusCode($response->getStatusCode());
383-
} catch (GuzzleException $e) {
384-
return false;
385-
}
384+
return $this->isSuccessStatusCode($response->getStatusCode());
386385
}
387386

388387
/**
@@ -392,6 +391,8 @@ public function trigger($channels, $name, $data, $socketId = null, $jsonEncoded
392391
* @param bool $jsonEncoded [optional] Defines if the data is already encoded
393392
*
394393
* @return bool
394+
* @throws GuzzleException
395+
* @throws JsonEncodeException on JSON encode failure.
395396
*/
396397
public function triggerBatch($batch = [], $jsonEncoded = false)
397398
{
@@ -404,21 +405,23 @@ public function triggerBatch($batch = [], $jsonEncoded = false)
404405
}
405406

406407
if (!$jsonEncoded) {
407-
$batch[$key]['data'] = json_encode($event['data']);
408+
$jsonData = json_encode($event['data']);
409+
410+
// json_encode returns false on failure
411+
if ($jsonData === false) {
412+
throw new JsonEncodeException($event['data'], json_last_error_msg(), json_last_error());
413+
}
414+
415+
$batch[$key]['data'] = $jsonData;
408416
}
409417
}
410418

411419
$postParams = [];
412420
$postParams['batch'] = $batch;
413421

422+
$response = $this->post('/events', [], $postParams);
414423

415-
try {
416-
$response = $this->post('/events', [], $postParams);
417-
418-
return $this->isSuccessStatusCode($response->getStatusCode());
419-
} catch (GuzzleException $e) {
420-
return false;
421-
}
424+
return $this->isSuccessStatusCode($response->getStatusCode());
422425
}
423426

424427
/**
@@ -429,7 +432,7 @@ public function triggerBatch($batch = [], $jsonEncoded = false)
429432
* @param array $queryParams API query params (see https://broadcastt.xyz/docs/References-‐-Rest-API)
430433
* @param array $postParams API post params (see https://broadcastt.xyz/docs/References-‐-Rest-API)
431434
*
432-
* @return Response
435+
* @return ResponseInterface
433436
* @throws GuzzleException
434437
*/
435438
private function post($path, $queryParams = [], $postParams = [])
@@ -453,7 +456,7 @@ private function post($path, $queryParams = [], $postParams = [])
453456
* @param string $path Path excluding /apps/{appId}
454457
* @param array $queryParams API query params (see https://broadcastt.xyz/docs/References-‐-Rest-API)
455458
*
456-
* @return Response See Broadcastt API docs
459+
* @return ResponseInterface See Broadcastt API docs
457460
* @throws GuzzleException
458461
*/
459462
public function get($path, $queryParams = [])
@@ -568,5 +571,4 @@ public function __set($name, $value)
568571
$this->modifiers[$name] = $value;
569572
}
570573
}
571-
572574
}

src/Exception/JsonEncodeException.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
namespace Broadcastt\Exception;
4+
5+
class JsonEncodeException extends \RuntimeException
6+
{
7+
private $data;
8+
9+
public function __construct($data, $message, $code, \Throwable $previous = null)
10+
{
11+
parent::__construct($message, $code, $previous);
12+
$this->data = $data;
13+
}
14+
15+
/**
16+
* @return mixed
17+
*/
18+
public function getData()
19+
{
20+
return $this->data;
21+
}
22+
}

tests/Feature/BroadcasttTriggerBatchTest.php

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@
77
use Broadcastt\Exception\InvalidDataException;
88
use Broadcastt\Exception\InvalidHostException;
99
use Broadcastt\Exception\InvalidSocketIdException;
10+
use Broadcastt\Exception\JsonEncodeException;
1011
use GuzzleHttp\Client;
12+
use GuzzleHttp\Exception\GuzzleException;
1113
use GuzzleHttp\Handler\MockHandler;
1214
use GuzzleHttp\HandlerStack;
1315
use GuzzleHttp\Middleware;
@@ -180,7 +182,7 @@ public function testCanNotTriggerBatchWithInvalidHost()
180182
$this->client->triggerBatch($batch);
181183
}
182184

183-
public function testCanTriggerBatchHandlePayloadTooLargeResponse()
185+
public function testCanTriggerBatchThrowExceptionOnPayloadTooLargeResponse()
184186
{
185187
$mockHandler = new MockHandler([
186188
new Response(413, [], '{}'),
@@ -202,8 +204,8 @@ public function testCanTriggerBatchHandlePayloadTooLargeResponse()
202204
$batch = [];
203205
$batch[] = ['channel' => 'test-channel', 'name' => 'test-event', 'data' => ['test-key' => 'test-val']];
204206
$batch[] = ['channel' => 'test-channel2', 'name' => 'test-event2', 'data' => ['test-key' => 'test-val2']];
205-
$response = $this->client->triggerBatch($batch);
206-
$this->assertFalse($response);
207+
$this->expectException(GuzzleException::class);
208+
$this->client->triggerBatch($batch);
207209
}
208210

209211
public function testCanTriggerBatchHandlePayloadTooLargeResponseWhenGuzzleExceptionsAreDisabled()
@@ -233,4 +235,19 @@ public function testCanTriggerBatchHandlePayloadTooLargeResponseWhenGuzzleExcept
233235
$this->assertFalse($response);
234236
}
235237

238+
public function testCanTriggerBatchThrowExceptionOnJsonEncodeFailure()
239+
{
240+
// data from https://www.php.net/manual/en/function.json-last-error.php
241+
$data = "\xB1\x31";
242+
243+
$batch = [];
244+
$batch[] = ['channel' => 'test-channel', 'name' => 'test-event', 'data' => $data];
245+
$this->expectException(JsonEncodeException::class);
246+
try {
247+
$this->client->triggerBatch($batch);
248+
} catch (JsonEncodeException $e) {
249+
$this->assertEquals($e->getData(), $data);
250+
throw $e;
251+
}
252+
}
236253
}

tests/Feature/BroadcasttTriggerTest.php

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44

55
use Broadcastt\BroadcasttClient;
66
use Broadcastt\Exception\InvalidSocketIdException;
7+
use Broadcastt\Exception\JsonEncodeException;
78
use Broadcastt\Exception\TooManyChannelsException;
89
use Broadcastt\Exception\InvalidHostException;
910
use GuzzleHttp\Client;
11+
use GuzzleHttp\Exception\GuzzleException;
1012
use GuzzleHttp\Handler\MockHandler;
1113
use GuzzleHttp\HandlerStack;
1214
use GuzzleHttp\Middleware;
@@ -165,7 +167,6 @@ public function testCanNotTriggerWithInvalidChannel($invalidChannel)
165167
$this->client->setGuzzleClient($guzzleClient);
166168

167169
$this->expectException(InvalidArgumentException::class);
168-
169170
$this->client->trigger($invalidChannel, 'test-event', '');
170171
}
171172

@@ -181,12 +182,11 @@ public function testCanNotTriggerWithMoreThanHundredChannel()
181182

182183
$this->client->setGuzzleClient($guzzleClient);
183184

184-
$this->expectException(TooManyChannelsException::class);
185-
186185
$channels = [];
187186
for ($i = 0; $i < 101; $i++) {
188187
$channels[] = 'test-channel' . $i;
189188
}
189+
$this->expectException(TooManyChannelsException::class);
190190
$this->client->trigger($channels, 'test-event', '');
191191
}
192192

@@ -207,7 +207,6 @@ public function testCanNotTriggerWithInvalidSocketId($invalidSocketId)
207207
$this->client->setGuzzleClient($guzzleClient);
208208

209209
$this->expectException(InvalidSocketIdException::class);
210-
211210
$this->client->trigger('test-channel', 'test-event', '', $invalidSocketId);
212211
}
213212

@@ -225,11 +224,10 @@ public function testCanNotTriggerWithInvalidHost()
225224
$this->client->host = 'http://test.xyz';
226225

227226
$this->expectException(InvalidHostException::class);
228-
229227
$this->client->trigger('test-channel', 'test-event', '');
230228
}
231229

232-
public function testCanTriggerHandlePayloadTooLargeResponse()
230+
public function testCanTriggerThrowExceptionOnPayloadTooLargeResponse()
233231
{
234232
$mockHandler = new MockHandler([
235233
new Response(413, [], '{}'),
@@ -248,8 +246,8 @@ public function testCanTriggerHandlePayloadTooLargeResponse()
248246

249247
$this->client->setGuzzleClient($guzzleClient);
250248

251-
$response = $this->client->trigger('test-channel', 'test-event', '');
252-
$this->assertFalse($response);
249+
$this->expectException(GuzzleException::class);
250+
$this->client->trigger('test-channel', 'test-event', '');
253251
}
254252

255253
public function testCanTriggerHandlePayloadTooLargeResponseWhenGuzzleExceptionsAreDisabled()
@@ -276,4 +274,17 @@ public function testCanTriggerHandlePayloadTooLargeResponseWhenGuzzleExceptionsA
276274
$this->assertFalse($response);
277275
}
278276

277+
public function testCanTriggerThrowExceptionOnJsonEncodeFailure()
278+
{
279+
// data from https://www.php.net/manual/en/function.json-last-error.php
280+
$data = "\xB1\x31";
281+
282+
$this->expectException(JsonEncodeException::class);
283+
try {
284+
$this->client->trigger('test-channel', 'test-event', $data);
285+
} catch (JsonEncodeException $e) {
286+
$this->assertEquals($e->getData(), $data);
287+
throw $e;
288+
}
289+
}
279290
}

0 commit comments

Comments
 (0)