@@ -239,6 +239,7 @@ export class WebStandardStreamableHTTPServerTransport implements Transport {
239239 private _enableDnsRebindingProtection : boolean ;
240240 private _retryInterval ?: number ;
241241 private _supportedProtocolVersions : string [ ] ;
242+ private _isClosing = false ;
242243
243244 sessionId ?: string ;
244245 onclose ?: ( ) => void ;
@@ -388,7 +389,14 @@ export class WebStandardStreamableHTTPServerTransport implements Transport {
388389 return ;
389390 }
390391
391- const primingEventId = await this . _eventStore . storeEvent ( streamId , { } as JSONRPCMessage ) ;
392+ let primingEventId : string ;
393+ try {
394+ primingEventId = await this . _eventStore . storeEvent ( streamId , { } as JSONRPCMessage ) ;
395+ } catch ( error ) {
396+ const err = error as Error ;
397+ this . onerror ?.( err ) ;
398+ throw err ;
399+ }
392400
393401 let primingEvent = `id: ${ primingEventId } \ndata: \n\n` ;
394402 if ( this . _retryInterval !== undefined ) {
@@ -887,14 +895,30 @@ export class WebStandardStreamableHTTPServerTransport implements Transport {
887895 }
888896
889897 async close ( ) : Promise < void > {
890- // Close all SSE connections
891- for ( const { cleanup } of this . _streamMapping . values ( ) ) {
892- cleanup ( ) ;
898+ if ( this . _isClosing ) return ;
899+ this . _isClosing = true ;
900+
901+ try {
902+ // Snapshot and clear the mapping before calling cleanup functions
903+ // to prevent re-entrant deletes from cancel callbacks
904+ const entries = [ ...this . _streamMapping . values ( ) ] ;
905+ this . _streamMapping . clear ( ) ;
906+
907+ // Close all SSE connections
908+ for ( const { cleanup } of entries ) {
909+ try {
910+ cleanup ( ) ;
911+ } catch {
912+ // Suppress cleanup errors
913+ }
914+ }
915+
916+ // Clear any pending responses
917+ this . _requestResponseMap . clear ( ) ;
918+ } finally {
919+ // Don't reset _isClosing - once closed, stay closed
893920 }
894- this . _streamMapping . clear ( ) ;
895921
896- // Clear any pending responses
897- this . _requestResponseMap . clear ( ) ;
898922 this . onclose ?.( ) ;
899923 }
900924
@@ -937,15 +961,23 @@ export class WebStandardStreamableHTTPServerTransport implements Transport {
937961 if ( requestId === undefined ) {
938962 // For standalone SSE streams, we can only send requests and notifications
939963 if ( isJSONRPCResultResponse ( message ) || isJSONRPCErrorResponse ( message ) ) {
940- throw new Error ( 'Cannot send a response on a standalone SSE stream unless resuming a previous client request' ) ;
964+ const err = new Error ( 'Cannot send a response on a standalone SSE stream unless resuming a previous client request' ) ;
965+ this . onerror ?.( err ) ;
966+ throw err ;
941967 }
942968
943969 // Generate and store event ID if event store is provided
944970 // Store even if stream is disconnected so events can be replayed on reconnect
945971 let eventId : string | undefined ;
946972 if ( this . _eventStore ) {
947- // Stores the event and gets the generated event ID
948- eventId = await this . _eventStore . storeEvent ( this . _standaloneSseStreamId , message ) ;
973+ try {
974+ // Stores the event and gets the generated event ID
975+ eventId = await this . _eventStore . storeEvent ( this . _standaloneSseStreamId , message ) ;
976+ } catch ( error ) {
977+ const err = error as Error ;
978+ this . onerror ?.( err ) ;
979+ throw err ;
980+ }
949981 }
950982
951983 const standaloneSse = this . _streamMapping . get ( this . _standaloneSseStreamId ) ;
@@ -964,7 +996,9 @@ export class WebStandardStreamableHTTPServerTransport implements Transport {
964996 // Get the response for this request
965997 const streamId = this . _requestToStreamMapping . get ( requestId ) ;
966998 if ( ! streamId ) {
967- throw new Error ( `No connection established for request ID: ${ String ( requestId ) } ` ) ;
999+ const err = new Error ( `No connection established for request ID: ${ String ( requestId ) } ` ) ;
1000+ this . onerror ?.( err ) ;
1001+ throw err ;
9681002 }
9691003
9701004 const stream = this . _streamMapping . get ( streamId ) ;
@@ -974,7 +1008,13 @@ export class WebStandardStreamableHTTPServerTransport implements Transport {
9741008 let eventId : string | undefined ;
9751009
9761010 if ( this . _eventStore ) {
977- eventId = await this . _eventStore . storeEvent ( streamId , message ) ;
1011+ try {
1012+ eventId = await this . _eventStore . storeEvent ( streamId , message ) ;
1013+ } catch ( error ) {
1014+ const err = error as Error ;
1015+ this . onerror ?.( err ) ;
1016+ throw err ;
1017+ }
9781018 }
9791019 // Write the event to the response stream
9801020 this . writeSSEEvent ( stream . controller , stream . encoder , message , eventId ) ;
@@ -989,7 +1029,9 @@ export class WebStandardStreamableHTTPServerTransport implements Transport {
9891029
9901030 if ( allResponsesReady ) {
9911031 if ( ! stream ) {
992- throw new Error ( `No connection established for request ID: ${ String ( requestId ) } ` ) ;
1032+ const err = new Error ( `No connection established for request ID: ${ String ( requestId ) } ` ) ;
1033+ this . onerror ?.( err ) ;
1034+ throw err ;
9931035 }
9941036 if ( this . _enableJsonResponse && stream . resolveJson ) {
9951037 // All responses ready, send as JSON
0 commit comments