@@ -193,6 +193,7 @@ async def __aexit__(self, exc_type, exc_val, exc_tb):
193
193
# Using BaseSession as a context manager should not block on exit (this
194
194
# would be very surprising behavior), so make sure to cancel the tasks
195
195
# in the task group.
196
+ self ._closed = True
196
197
self ._task_group .cancel_scope .cancel ()
197
198
return await self ._task_group .__aexit__ (exc_type , exc_val , exc_tb )
198
199
@@ -256,12 +257,21 @@ async def send_notification(self, notification: SendNotificationT) -> None:
256
257
Emits a notification, which is a one-way message that does not expect
257
258
a response.
258
259
"""
259
- jsonrpc_notification = JSONRPCNotification (
260
- jsonrpc = "2.0" ,
261
- ** notification .model_dump (by_alias = True , mode = "json" , exclude_none = True ),
262
- )
260
+ # Skip sending notifications if the session is closed
261
+ if self ._closed :
262
+ return
263
+
264
+ try :
265
+ jsonrpc_notification = JSONRPCNotification (
266
+ jsonrpc = "2.0" ,
267
+ ** notification .model_dump (by_alias = True , mode = "json" , exclude_none = True ),
268
+ )
263
269
264
- await self ._write_stream .send (JSONRPCMessage (jsonrpc_notification ))
270
+ await self ._write_stream .send (JSONRPCMessage (jsonrpc_notification ))
271
+ except Exception :
272
+ # Ignore notification send errors during session cleanup
273
+ if not self ._closed :
274
+ raise
265
275
266
276
async def _send_response (
267
277
self , request_id : RequestId , response : SendResultT | ErrorData
@@ -279,6 +289,19 @@ async def _send_response(
279
289
)
280
290
await self ._write_stream .send (JSONRPCMessage (jsonrpc_response ))
281
291
292
+ def _should_validate_notification (self , message_root : JSONRPCNotification ) -> bool :
293
+ """
294
+ Determines if a notification should be validated.
295
+ Internal notifications (like cancelled) should be ignored.
296
+ """
297
+ try :
298
+ return (
299
+ getattr (message_root , "method" , None ) != "cancelled" and
300
+ not self ._closed
301
+ )
302
+ except :
303
+ return False
304
+
282
305
async def _receive_loop (self ) -> None :
283
306
async with (
284
307
self ._read_stream ,
@@ -378,4 +401,4 @@ def incoming_messages(
378
401
| ReceiveNotificationT
379
402
| Exception
380
403
]:
381
- return self ._incoming_message_stream_reader
404
+ return self ._incoming_message_stream_reader
0 commit comments