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) {
|
constructor(connectionStream) {
|
||||||
this.connectionStream = connectionStream;
|
this.connectionStream = connectionStream;
|
||||||
this.notificationChannel = new SafeEventEmitter();
|
this.notificationChannel = new SafeEventEmitter();
|
||||||
|
this.uncaughtErrorChannel = new SafeEventEmitter();
|
||||||
this.requests = new Map();
|
this.requests = new Map();
|
||||||
this.connectionStream.on('data', this.handleResponse.bind(this));
|
this.connectionStream.on('data', this.handleResponse.bind(this));
|
||||||
this.connectionStream.on('end', this.close.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() {
|
close() {
|
||||||
this.notificationChannel.removeAllListeners();
|
this.notificationChannel.removeAllListeners();
|
||||||
|
this.uncaughtErrorChannel.removeAllListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
handleResponse(data) {
|
handleResponse(data) {
|
||||||
const { id, result, error, method, params } = data;
|
const { id, result, error, method, params } = data;
|
||||||
|
const isNotification = id === undefined && error === undefined;
|
||||||
const cb = this.requests.get(id);
|
const cb = this.requests.get(id);
|
||||||
|
|
||||||
if (method && params && id) {
|
if (method && params && !isNotification) {
|
||||||
// dont handle server-side to client-side requests
|
// dont handle server-side to client-side requests
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (method && params && !id) {
|
if (method && params && isNotification) {
|
||||||
// handle servier-side to client-side notification
|
// handle servier-side to client-side notification
|
||||||
this.notificationChannel.emit('notification', data);
|
this.notificationChannel.emit('notification', data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!cb) {
|
|
||||||
// not found in request list
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
const e = new EthereumRpcError(error.code, error.message, error.data);
|
const e = new EthereumRpcError(error.code, error.message, error.data);
|
||||||
// preserve the stack from serializeError
|
// preserve the stack from serializeError
|
||||||
e.stack = error.stack;
|
e.stack = error.stack;
|
||||||
|
if (cb) {
|
||||||
this.requests.delete(id);
|
this.requests.delete(id);
|
||||||
cb(e);
|
cb(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
this.uncaughtErrorChannel.emit('error', e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cb) {
|
||||||
|
// not found in request list
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
this.requests.delete(id);
|
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