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:
parent
ce67e1bfcd
commit
0cb0f7c2c2
@ -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);
|
||||
|
||||
|
@ -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',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user