66 JsonRpcResponse ,
77 JsonRpcNotification ,
88 isJsonRpcRequest ,
9- isNullOrUndefined ,
109} from '@metamask/utils' ;
1110import { errorCodes , EthereumRpcError , serializeError } from 'eth-rpc-errors' ;
1211
@@ -49,7 +48,8 @@ interface JsonRpcEngineArgs {
4948 * defined as a JSON-RPC request without an `id` property. If this option is
5049 * _not_ provided, notifications will be treated the same as requests. If this
5150 * option _is_ provided, notifications will be passed to the handler
52- * function without touching the engine's middleware stack.
51+ * function without touching the engine's middleware stack. This function
52+ * should not** throw or reject.
5353 */
5454 notificationHandler ?: JsonRpcNotificationHandler < unknown > ;
5555}
@@ -72,7 +72,8 @@ export class JsonRpcEngine extends SafeEventEmitter {
7272 * without an `id` property. If this option is _not_ provided, notifications
7373 * will be treated the same as requests. If this option _is_ provided,
7474 * notifications will be passed to the handler function without touching
75- * the engine's middleware stack.
75+ * the engine's middleware stack. This function **should not** throw or
76+ * reject.
7677 */
7778 constructor ( { notificationHandler } : JsonRpcEngineArgs = { } ) {
7879 super ( ) ;
@@ -239,7 +240,8 @@ export class JsonRpcEngine extends SafeEventEmitter {
239240 // Filter out falsy responses from notifications
240241 )
241242 ) . filter (
242- ( response ) => ! isNullOrUndefined ( response ) ,
243+ // Filter out any notification responses.
244+ ( response ) => response !== undefined ,
243245 ) as JsonRpcResponse < unknown > [ ] ;
244246
245247 // 3. Return batch response
@@ -265,10 +267,16 @@ export class JsonRpcEngine extends SafeEventEmitter {
265267 private _promiseHandle (
266268 req : JsonRpcRequest < unknown > | JsonRpcNotification < unknown > ,
267269 ) : Promise < JsonRpcResponse < unknown > | void > {
268- return new Promise ( ( resolve ) => {
269- this . _handle ( req , ( _err , res ) => {
270- // There will always be a response, and it will always have any error
271- // that is caught and propagated.
270+ return new Promise ( ( resolve , reject ) => {
271+ this . _handle ( req , ( error , res ) => {
272+ // For notifications, the response will be `undefined`, and any caught
273+ // errors are unexpected and should be surfaced to the caller.
274+ if ( error && res === undefined ) {
275+ reject ( error ) ;
276+ }
277+
278+ // Excepting notifications, there will always be a response, and it will
279+ // always have any error that is caught and propagated.
272280 resolve ( res ) ;
273281 } ) ;
274282 } ) ;
@@ -324,7 +332,11 @@ export class JsonRpcEngine extends SafeEventEmitter {
324332 // We can't use isJsonRpcNotification here because that narrows callerReq to
325333 // "never" after the if clause for unknown reasons.
326334 if ( this . _notificationHandler && ! isJsonRpcRequest ( callerReq ) ) {
327- await this . _notificationHandler ( callerReq ) ;
335+ try {
336+ await this . _notificationHandler ( callerReq ) ;
337+ } catch ( error ) {
338+ return callback ( error ) ;
339+ }
328340 return callback ( null ) ;
329341 }
330342
0 commit comments