6
6
JsonRpcResponse ,
7
7
JsonRpcNotification ,
8
8
isJsonRpcRequest ,
9
- isNullOrUndefined ,
10
9
} from '@metamask/utils' ;
11
10
import { errorCodes , EthereumRpcError , serializeError } from 'eth-rpc-errors' ;
12
11
@@ -49,7 +48,8 @@ interface JsonRpcEngineArgs {
49
48
* defined as a JSON-RPC request without an `id` property. If this option is
50
49
* _not_ provided, notifications will be treated the same as requests. If this
51
50
* 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.
53
53
*/
54
54
notificationHandler ?: JsonRpcNotificationHandler < unknown > ;
55
55
}
@@ -72,7 +72,8 @@ export class JsonRpcEngine extends SafeEventEmitter {
72
72
* without an `id` property. If this option is _not_ provided, notifications
73
73
* will be treated the same as requests. If this option _is_ provided,
74
74
* 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.
76
77
*/
77
78
constructor ( { notificationHandler } : JsonRpcEngineArgs = { } ) {
78
79
super ( ) ;
@@ -239,7 +240,8 @@ export class JsonRpcEngine extends SafeEventEmitter {
239
240
// Filter out falsy responses from notifications
240
241
)
241
242
) . filter (
242
- ( response ) => ! isNullOrUndefined ( response ) ,
243
+ // Filter out any notification responses.
244
+ ( response ) => response !== undefined ,
243
245
) as JsonRpcResponse < unknown > [ ] ;
244
246
245
247
// 3. Return batch response
@@ -265,10 +267,16 @@ export class JsonRpcEngine extends SafeEventEmitter {
265
267
private _promiseHandle (
266
268
req : JsonRpcRequest < unknown > | JsonRpcNotification < unknown > ,
267
269
) : 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.
272
280
resolve ( res ) ;
273
281
} ) ;
274
282
} ) ;
@@ -324,7 +332,11 @@ export class JsonRpcEngine extends SafeEventEmitter {
324
332
// We can't use isJsonRpcNotification here because that narrows callerReq to
325
333
// "never" after the if clause for unknown reasons.
326
334
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
+ }
328
340
return callback ( null ) ;
329
341
}
330
342
0 commit comments