Unverified Commit aa36b38b authored by Amaury Martiny's avatar Amaury Martiny Committed by GitHub
Browse files

fix: Only emit correctly-formed JSONRPC message (#561)

* console.warn when parsing error

* Add some logs

* Concatenate previous message if ill-formed

* Use debug instead of console.log
parent f8ccea14
Pipeline #54876 failed with stages
in 17 minutes and 27 seconds
......@@ -31,10 +31,25 @@ class IpcChannel extends EventEmitter {
this._sendQueued();
resolve(true);
});
// We get data from the socket by chunks, and 1 chunk !== 1 Rpc message
// Sometimes 1 chunk is multiple messages, sometimes we get partial
// messages.
// https://github.com/paritytech/fether/issues/562
// The last element in a '\n'-separate chunk. Will be `""` if the
// last element was a correctly-formed message, or will hold the
// ill-formed message otherwise.
let lastData = '';
socket.on('data', data_ => {
const data = data_.toString();
// Sometimes we receive multiple messages at once
const messages = data.split(/\r?\n/).filter(Boolean);
// If the last data was truncated, then we concatenate to the new data
// we just received
const data = `${lastData}${data_.toString()}`;
// All messages are separated by a '\n'
const messages = data.split(/\n/);
lastData = messages.pop(); // Will hold "" or an ill-formed JSONRPC message
messages.forEach(data => {
this.emit('message', data);
});
......
......@@ -14,11 +14,15 @@
// You should have received a copy of the GNU General Public License
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
import * as postMessage from './postMessage';
import EventEmitter from 'eventemitter3';
import Debug from './debug';
import * as postMessage from './postMessage';
const debug = Debug('PostMessageProvider');
export default class PostMessageProvider extends EventEmitter {
constructor (destination, source) {
constructor (destination) {
super();
this._destination = destination || window.parent;
......@@ -136,7 +140,17 @@ export default class PostMessageProvider extends EventEmitter {
}
_receiveMessage (raw) {
const parsed = JSON.parse(raw);
let parsed;
try {
parsed = JSON.parse(raw);
} catch (err) {
// Should not happen anymore, since the following issue is fixed
// https://github.com/paritytech/fether/issues/562
debug(`Cannot parse ${raw}. Ignoring message.`);
return;
}
const { id, error } = parsed;
const subscription = parsed.params && parsed.params.subscription;
......@@ -144,12 +158,32 @@ export default class PostMessageProvider extends EventEmitter {
// subscription notification
const result = parsed.params.result;
let messageId = this._subscriptionsToId[subscription];
this._messages[messageId].callback(error && new Error(error), result);
// Sometimes we receive results for a subscription that we have never
// seen before. Should not happen.
if (!this._messages[messageId]) {
debug(`Got result for unknown subscription ${subscription}`);
return;
}
this._messages[messageId].callback(
error && new Error(error.message),
result
);
} else {
// Sometimes we receive results for an id that we have never seen before.
// Should not happen.
if (!this._messages[id]) {
debug(`Got result for unknown id ${id}`);
return;
}
// request response
const result = parsed.result;
if (error) {
this._messages[id].reject(new Error(error));
this._messages[id].reject(new Error(error.message));
} else {
this._messages[id].resolve(result);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment