@@ -24,6 +24,7 @@ import {
2424 UnaryHandler ,
2525} from '@/rpc/handlers' ;
2626import * as middlewareUtils from '@/rpc/utils/middleware' ;
27+ import { promise } from '@/utils' ;
2728import * as rpcTestUtils from './utils' ;
2829
2930describe ( `${ RPCServer . name } ` , ( ) => {
@@ -454,13 +455,70 @@ describe(`${RPCServer.name}`, () => {
454455 } ,
455456 ) ;
456457 testProp (
457- 'should emit stream error' ,
458+ 'should emit stream error if input stream fails ' ,
458459 [ specificMessageArb ] ,
459460 async ( messages ) => {
461+ const handlerEndedProm = promise ( ) ;
462+ class TestMethod extends DuplexHandler {
463+ public async * handle ( input ) : AsyncIterable < JSONValue > {
464+ try {
465+ for await ( const _ of input ) {
466+ // Consume but don't yield anything
467+ }
468+ } finally {
469+ handlerEndedProm . resolveP ( ) ;
470+ }
471+ }
472+ }
473+ const rpcServer = await RPCServer . createRPCServer ( {
474+ manifest : {
475+ testMethod : new TestMethod ( { } ) ,
476+ } ,
477+ logger,
478+ } ) ;
479+ let resolve ;
480+ rpcServer . addEventListener ( 'error' , ( thing : RPCErrorEvent ) => {
481+ resolve ( thing ) ;
482+ } ) ;
483+ const passThroughStreamIn = new TransformStream < Uint8Array , Uint8Array > ( ) ;
484+ const [ outputResult , outputStream ] = rpcTestUtils . streamToArray < Buffer > ( ) ;
485+ const readWriteStream : ReadableWritablePair < Uint8Array , Uint8Array > = {
486+ readable : passThroughStreamIn . readable ,
487+ writable : outputStream ,
488+ } ;
489+ rpcServer . handleStream ( readWriteStream , { } as ConnectionInfo ) ;
490+ const writer = passThroughStreamIn . writable . getWriter ( ) ;
491+ // Write messages
492+ for ( const message of messages ) {
493+ await writer . write ( Buffer . from ( JSON . stringify ( message ) ) ) ;
494+ }
495+ // Abort stream
496+ const writerReason = Symbol ( 'writerAbort' ) ;
497+ await writer . abort ( writerReason ) ;
498+ // We should get an error RPC message
499+ await expect ( outputResult ) . toResolve ( ) ;
500+ const errorMessage = JSON . parse ( ( await outputResult ) [ 0 ] . toString ( ) ) ;
501+ // Parse without error
502+ rpcUtils . parseJSONRPCResponseError ( errorMessage ) ;
503+ // Check that the handler was cleaned up.
504+ await expect ( handlerEndedProm . p ) . toResolve ( ) ;
505+ await rpcServer . destroy ( ) ;
506+ } ,
507+ { numRuns : 1 } ,
508+ ) ;
509+ testProp . only (
510+ 'should emit stream error if output stream fails' ,
511+ [ specificMessageArb ] ,
512+ async ( messages ) => {
513+ const handlerEndedProm = promise ( ) ;
460514 class TestMethod extends DuplexHandler {
461515 public async * handle ( input ) : AsyncIterable < JSONValue > {
462516 // Echo input
463- yield * input ;
517+ try {
518+ yield * input ;
519+ } finally {
520+ handlerEndedProm . resolveP ( ) ;
521+ }
464522 }
465523 }
466524 const rpcServer = await RPCServer . createRPCServer ( {
@@ -494,14 +552,18 @@ describe(`${RPCServer.name}`, () => {
494552 await reader . read ( ) ;
495553 }
496554 // Abort stream
497- const writerReason = Symbol ( 'writerAbort' ) ;
555+ // const writerReason = Symbol('writerAbort');
498556 const readerReason = Symbol ( 'readerAbort' ) ;
499- await writer . abort ( writerReason ) ;
557+ // Await writer.abort(writerReason);
500558 await reader . cancel ( readerReason ) ;
501559 // We should get an error event
502560 const event = await errorProm ;
503- expect ( event . detail . cause ) . toContain ( writerReason ) ;
504- expect ( event . detail . cause ) . toContain ( readerReason ) ;
561+ await writer . close ( ) ;
562+ // Expect(event.detail.cause).toContain(writerReason);
563+ expect ( event . detail ) . toBeInstanceOf ( rpcErrors . ErrorRPCOutputStreamError ) ;
564+ expect ( event . detail . cause ) . toBe ( readerReason ) ;
565+ // Check that the handler was cleaned up.
566+ await expect ( handlerEndedProm . p ) . toResolve ( ) ;
505567 await rpcServer . destroy ( ) ;
506568 } ,
507569 { numRuns : 1 } ,
0 commit comments