Skip to content

Commit 6653656

Browse files
committed
Ensure we catch all exceptions when processing data and forward them to the handleError method
1 parent 218140e commit 6653656

File tree

1 file changed

+32
-25
lines changed

1 file changed

+32
-25
lines changed

src/React/Decoder.php

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
use EdgeTelemetrics\JSON_RPC\Request;
1515
use EdgeTelemetrics\JSON_RPC\Response;
1616
use EdgeTelemetrics\JSON_RPC\Error;
17+
use function array_key_exists;
18+
use function is_array;
1719

1820
/**
1921
* The Decoder / Parser reads from a NDJSON stream and emits JSON-RPC notifications/requests/responses
@@ -97,38 +99,43 @@ public function pipe(WritableStreamInterface $dest, array $options = array())
9799
*/
98100
public function handleData($input)
99101
{
100-
/** Check if we are batch request */
101-
if (!isset($input[0]))
102-
{
103-
$input = [$input];
104-
}
105-
106-
/** Process responses whether batch or individual one by one and emit it up the the higher levels */
107-
foreach($input as $data) {
108-
if (!isset($data['jsonrpc'])) {
109-
throw new RuntimeException('Unable to decode. Missing required jsonrpc field');
102+
try {
103+
if (!is_array($input)) {
104+
throw new RuntimeException('Decoded JSON data is not an array');
110105
}
111106

112-
if ($data['jsonrpc'] != RpcMessageInterface::JSONRPC_VERSION) {
113-
throw new RuntimeException('Unknown JSON-RPC version string');
107+
/** Check if we are batch request */
108+
//if (!array_is_list($input))
109+
if (!array_key_exists(0, $input)) {
110+
$input = [$input];
114111
}
115112

116-
if (isset($data['method'])) {
117-
// If the ID field is contained in the request even if NULL then we consider it to be Request
118-
if (isset($data['id']) || array_key_exists('id', $data)) {
119-
$jsonrpc = new Request($data['method'], $data['params'] ?? [], $data['id']);
113+
/** Process responses whether batch or individual one by one and emit the jsonrpc */
114+
foreach ($input as $data) {
115+
if (!isset($data['jsonrpc']) || $data['jsonrpc'] !== RpcMessageInterface::JSONRPC_VERSION) {
116+
throw new RuntimeException('Unknown or missing JSON-RPC version string');
117+
}
118+
119+
if (isset($data['method'])) {
120+
// If the ID field is contained in the request even if NULL then we consider it to be Request
121+
if (isset($data['id']) || array_key_exists('id', $data)) {
122+
$jsonrpc = new Request($data['method'], $data['params'] ?? [], $data['id']);
123+
} else {
124+
$jsonrpc = new Notification($data['method'], $data['params'] ?? []);
125+
}
126+
} elseif (isset($data['result'])) {
127+
$jsonrpc = new Response($data['id'], $data['result']);
128+
} elseif (isset($data['error'])) {
129+
$error = new Error($data['error']['code'], $data['error']['message'],
130+
$data['error']['data'] ?? null);
131+
$jsonrpc = new Response($data['id'], $error);
120132
} else {
121-
$jsonrpc = new Notification($data['method'], $data['params'] ?? []);
133+
throw new RuntimeException('Unable to decode json rpc packet, failed to identify Request, Response or Error record');
122134
}
123-
} elseif (isset($data['result'])) {
124-
$jsonrpc = new Response($data['id'], $data['result']);
125-
} elseif (isset($data['error'])) {
126-
$error = new Error($data['error']['code'], $data['error']['message'], $data['error']['data'] ?? null);
127-
$jsonrpc = new Response($data['id'], $error);
128-
} else {
129-
throw new RuntimeException('Unable to decode json rpc packet');
135+
$this->emit('data', [$jsonrpc]);
130136
}
131-
$this->emit('data', [$jsonrpc]);
137+
} catch (\Throwable $ex) {
138+
$this->handleError($ex);
132139
}
133140
}
134141

0 commit comments

Comments
 (0)