1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-12-23 09:52:26 +01:00

fix metaRPCClientFactory id handling (#11116)

* fix metaRPCClientFactory id handling
This commit is contained in:
Shane 2021-05-17 14:46:00 -07:00 committed by Dan Miller
parent ce67e1bfcd
commit 0cb0f7c2c2
2 changed files with 76 additions and 8 deletions

View File

@ -6,6 +6,7 @@ class MetaRPCClient {
constructor(connectionStream) {
this.connectionStream = connectionStream;
this.notificationChannel = new SafeEventEmitter();
this.uncaughtErrorChannel = new SafeEventEmitter();
this.requests = new Map();
this.connectionStream.on('data', this.handleResponse.bind(this));
this.connectionStream.on('end', this.close.bind(this));
@ -17,36 +18,49 @@ class MetaRPCClient {
});
}
onUncaughtError(handler) {
this.uncaughtErrorChannel.addListener('error', (error) => {
handler(error);
});
}
close() {
this.notificationChannel.removeAllListeners();
this.uncaughtErrorChannel.removeAllListeners();
}
handleResponse(data) {
const { id, result, error, method, params } = data;
const isNotification = id === undefined && error === undefined;
const cb = this.requests.get(id);
if (method && params && id) {
if (method && params && !isNotification) {
// dont handle server-side to client-side requests
return;
}
if (method && params && !id) {
if (method && params && isNotification) {
// handle servier-side to client-side notification
this.notificationChannel.emit('notification', data);
return;
}
if (!cb) {
// not found in request list
return;
}
if (error) {
const e = new EthereumRpcError(error.code, error.message, error.data);
// preserve the stack from serializeError
e.stack = error.stack;
if (cb) {
this.requests.delete(id);
cb(e);
return;
}
this.uncaughtErrorChannel.emit('error', e);
return;
}
if (!cb) {
// not found in request list
return;
}
this.requests.delete(id);

View File

@ -85,4 +85,58 @@ describe('metaRPCClientFactory', function () {
});
});
});
it('should be able to handle notifications', function (done) {
const streamTest = createThoughStream();
const metaRPCClient = metaRPCClientFactory(streamTest);
metaRPCClient.onNotification((notification) => {
assert(notification.method, 'foobarbaz');
done();
});
// send a notification
streamTest.write({
jsonrpc: '2.0',
method: 'foobarbaz',
params: ['bar'],
});
});
it('should be able to handle errors with no id', function (done) {
const streamTest = createThoughStream();
const metaRPCClient = metaRPCClientFactory(streamTest);
metaRPCClient.onUncaughtError((error) => {
assert(error.code, 1);
done();
});
streamTest.write({
jsonrpc: '2.0',
error: {
code: 1,
message: 'error msg',
},
});
});
it('should be able to handle errors with null id', function (done) {
const streamTest = createThoughStream();
const metaRPCClient = metaRPCClientFactory(streamTest);
metaRPCClient.onUncaughtError((error) => {
assert(error.code, 1);
done();
});
streamTest.write({
jsonrpc: '2.0',
id: null,
error: {
code: 1,
message: 'error msg',
},
});
});
});