11import SafeEventEmitter from '@metamask/safe-event-emitter' ;
22import { errorCodes , EthereumRpcError , serializeError } from 'eth-rpc-errors' ;
3- import { isJsonRpcRequest } from './utils' ;
3+ import { isJsonRpcNotification , isJsonRpcRequest } from './utils' ;
44
55type Maybe < T > = Partial < T > | null | undefined ;
66
@@ -128,7 +128,7 @@ export class JsonRpcEngine extends SafeEventEmitter {
128128 }
129129
130130 /**
131- * Add a middleware function to the engine's notification middleware stack.
131+ * Adds a middleware function to the engine's notification middleware stack.
132132 *
133133 * @param middleware - The notification middleware function to add.
134134 */
@@ -228,8 +228,17 @@ export class JsonRpcEngine extends SafeEventEmitter {
228228 asMiddleware ( ) : JsonRpcMiddleware < unknown , unknown > {
229229 return async ( req , res , next , end ) => {
230230 try {
231+ if ( isJsonRpcNotification ( req ) ) {
232+ // This will invoke the end callback.
233+ return await JsonRpcEngine . _processNotification (
234+ req ,
235+ this . _notificationMiddleware ,
236+ ( ) => end ( ) ,
237+ ) ;
238+ }
239+
231240 const [ middlewareError , isComplete , returnHandlers ] =
232- await JsonRpcEngine . _runAllMiddleware (
241+ await JsonRpcEngine . _runAllRequestMiddleware (
233242 req ,
234243 res ,
235244 this . _requestMiddleware ,
@@ -334,7 +343,7 @@ export class JsonRpcEngine extends SafeEventEmitter {
334343 */
335344 private async _handle (
336345 callerReq : JsonRpcRequest < unknown > | JsonRpcNotification < unknown > ,
337- callback : ( error : unknown , response ?: JsonRpcResponse < unknown > ) => void ,
346+ callback : ( error ? : unknown , response ?: JsonRpcResponse < unknown > ) => void ,
338347 ) : Promise < void > {
339348 if (
340349 ! callerReq ||
@@ -355,30 +364,32 @@ export class JsonRpcEngine extends SafeEventEmitter {
355364 `Must specify a string method. Received: ${ typeof callerReq . method } ` ,
356365 { request : callerReq } ,
357366 ) ;
358- return callback ( error , {
359- id : ( callerReq as any ) . id ?? null ,
360- jsonrpc : '2.0' ,
361- error,
362- } ) ;
363- }
364367
365- let error : JsonRpcEngineCallbackError = null ;
368+ if ( isJsonRpcRequest ( callerReq ) ) {
369+ return callback ( error , {
370+ id : ( callerReq as any ) . id ?? null ,
371+ jsonrpc : '2.0' ,
372+ error,
373+ } ) ;
374+ }
375+ // Do not reply to notifications, even malformed ones.
376+ return callback ( null ) ;
377+ }
366378
367379 // Handle notifications.
368380 // We can't use isJsonRpcNotification here because that narrows callerReq to
369381 // "never" after the if clause for unknown reasons.
370382 if ( ! isJsonRpcRequest ( callerReq ) ) {
371- try {
372- await JsonRpcEngine . _processNotification (
373- { ...callerReq } ,
374- this . _notificationMiddleware ,
375- ) ;
376- } catch ( _error ) {
377- error = _error ;
378- }
379- return callback ( error ) ;
383+ // This will invoke the callback.
384+ return await JsonRpcEngine . _processNotification (
385+ { ...callerReq } ,
386+ this . _notificationMiddleware ,
387+ callback ,
388+ ) ;
380389 }
381390
391+ let error : JsonRpcEngineCallbackError = null ;
392+
382393 // Handle requests.
383394 const req : JsonRpcRequest < unknown > = { ...callerReq } ;
384395 const res : PendingJsonRpcResponse < unknown > = {
@@ -407,17 +418,28 @@ export class JsonRpcEngine extends SafeEventEmitter {
407418
408419 /**
409420 * Runs all notification middleware on the specified notification.
421+ * Does not throw.
410422 *
411423 * @param notification - The notification object to process.
412- * @param notificationMiddlewares - The stack of notification middleware functions.
424+ * @param notificationMiddlewares - The stack of notification middleware
425+ * functions.
426+ * @param callback - Callback from {@link JsonRpcEngine._handle} or
427+ * {@link JsonRpcEngineEndCallback}. Will always be invoked with nothing,
428+ * because notifications must not be responded to.
413429 */
414430 private static async _processNotification (
415431 notification : JsonRpcNotification < unknown > ,
416432 notificationMiddlewares : JsonRpcNotificationMiddleware < unknown > [ ] ,
433+ callback : ( error ?: unknown , response ?: JsonRpcResponse < unknown > ) => void ,
417434 ) : Promise < void > {
418- for ( const middleware of notificationMiddlewares ) {
419- await middleware ( notification ) ;
435+ try {
436+ for ( const middleware of notificationMiddlewares ) {
437+ await middleware ( notification ) ;
438+ }
439+ } catch ( middlewareError ) {
440+ console . error ( middlewareError ) ;
420441 }
442+ callback ( null ) ;
421443 }
422444
423445 /**
@@ -435,7 +457,11 @@ export class JsonRpcEngine extends SafeEventEmitter {
435457 requestMiddlewares : JsonRpcMiddleware < unknown , unknown > [ ] ,
436458 ) : Promise < void > {
437459 const [ error , isComplete , returnHandlers ] =
438- await JsonRpcEngine . _runAllMiddleware ( req , res , requestMiddlewares ) ;
460+ await JsonRpcEngine . _runAllRequestMiddleware (
461+ req ,
462+ res ,
463+ requestMiddlewares ,
464+ ) ;
439465
440466 // Throw if "end" was not called, or if the response has neither a result
441467 // nor an error.
@@ -462,7 +488,7 @@ export class JsonRpcEngine extends SafeEventEmitter {
462488 * a boolean indicating whether the request was completed, and an array of
463489 * middleware-defined return handlers.
464490 */
465- private static async _runAllMiddleware (
491+ private static async _runAllRequestMiddleware (
466492 req : JsonRpcRequest < unknown > ,
467493 res : PendingJsonRpcResponse < unknown > ,
468494 requestMiddlewares : JsonRpcMiddleware < unknown , unknown > [ ] ,
@@ -479,7 +505,7 @@ export class JsonRpcEngine extends SafeEventEmitter {
479505
480506 // Go down stack of middleware, call and collect optional returnHandlers
481507 for ( const middleware of requestMiddlewares ) {
482- [ error , isComplete ] = await JsonRpcEngine . _runMiddleware (
508+ [ error , isComplete ] = await JsonRpcEngine . _runRequestMiddleware (
483509 req ,
484510 res ,
485511 middleware ,
@@ -503,7 +529,7 @@ export class JsonRpcEngine extends SafeEventEmitter {
503529 * @returns An array of any error encountered during middleware exection,
504530 * and a boolean indicating whether the request should end.
505531 */
506- private static _runMiddleware (
532+ private static _runRequestMiddleware (
507533 req : JsonRpcRequest < unknown > ,
508534 res : PendingJsonRpcResponse < unknown > ,
509535 middleware : JsonRpcMiddleware < unknown , unknown > ,
@@ -576,7 +602,7 @@ export class JsonRpcEngine extends SafeEventEmitter {
576602 *
577603 * @param req - The request object.
578604 * @param res - The response object.
579- * @param isComplete - Boolean from {@link JsonRpcEngine._runAllMiddleware }
605+ * @param isComplete - Boolean from {@link JsonRpcEngine._runAllRequestMiddleware }
580606 * indicating whether a middleware ended the request.
581607 */
582608 private static _checkForCompletion (
0 commit comments