@@ -362,8 +362,9 @@ def test_close_stops_watchdog(self):
362362 from pubnub .request_handlers .httpx import HttpxRequestHandler
363363
364364 handler = HttpxRequestHandler (MagicMock ())
365+ session = handler ._ensure_session ()
365366 # Start the watchdog by setting a deadline
366- handler ._watchdog .set_deadline (handler . session , time .time () + 300 )
367+ handler ._watchdog .set_deadline (session , time .time () + 300 )
367368 self .assertIsNotNone (handler ._watchdog ._thread )
368369
369370 handler .close ()
@@ -391,11 +392,11 @@ def _make_handler(self):
391392 def test_closed_session_is_recreated_on_next_request (self ):
392393 """After session.close(), the next _invoke_request should recreate the session."""
393394 handler = self ._make_handler ()
394- original_session = handler .session
395+ original_session = handler ._ensure_session ()
395396
396397 # Simulate what the watchdog does
397- handler . session .close ()
398- self .assertTrue (handler .session .is_closed )
398+ original_session .close ()
399+ self .assertTrue (handler ._session .is_closed )
399400
400401 # Build minimal request options
401402 from pubnub .structures import RequestOptions , PlatformOptions
@@ -422,17 +423,17 @@ def test_closed_session_is_recreated_on_next_request(self):
422423 except Exception :
423424 pass
424425
425- self .assertFalse (handler .session .is_closed )
426- self .assertIsNot (handler .session , original_session )
426+ self .assertFalse (handler ._session .is_closed )
427+ self .assertIsNot (handler ._session , original_session )
427428
428429 handler .close ()
429430
430431 def test_open_session_is_not_recreated (self ):
431432 """An open session should not be replaced."""
432433 handler = self ._make_handler ()
433- original_session = handler .session
434+ original_session = handler ._ensure_session ()
434435
435- self .assertFalse (handler .session .is_closed )
436+ self .assertFalse (handler ._session .is_closed )
436437
437438 from pubnub .structures import RequestOptions , PlatformOptions
438439 p_options = MagicMock (spec = PlatformOptions )
@@ -457,18 +458,18 @@ def test_open_session_is_not_recreated(self):
457458 except Exception :
458459 pass
459460
460- self .assertIs (handler .session , original_session )
461+ self .assertIs (handler ._session , original_session )
461462 handler .close ()
462463
463464 def test_watchdog_trigger_with_timeout_exception_recreates_session (self ):
464465 """When watchdog triggers and the request gets TimeoutException, session should be recreated."""
465466 handler = self ._make_handler ()
466- original_session = handler .session
467+ original_session = handler ._ensure_session ()
467468
468469 # Set up watchdog as triggered
469- handler ._watchdog .set_deadline (handler . session , time .time () - 1 )
470+ handler ._watchdog .set_deadline (original_session , time .time () - 1 )
470471 time .sleep (0.3 )
471- self .assertTrue (handler . session .is_closed )
472+ self .assertTrue (original_session .is_closed )
472473
473474 from pubnub .structures import RequestOptions , PlatformOptions
474475 p_options = MagicMock (spec = PlatformOptions )
@@ -493,9 +494,9 @@ def test_watchdog_trigger_with_timeout_exception_recreates_session(self):
493494 except Exception :
494495 pass
495496
496- # Session should have been recreated (either by is_closed check or watchdog trigger handler)
497- self .assertFalse (handler .session .is_closed )
498- self .assertIsNot (handler .session , original_session )
497+ # Session should have been recreated by _ensure_session() since original was closed
498+ self .assertFalse (handler ._session .is_closed )
499+ self .assertIsNot (handler ._session , original_session )
499500
500501 handler ._watchdog .stop ()
501502 handler .close ()
@@ -509,10 +510,11 @@ def test_reconnection_time_request_works_after_session_close(self):
509510 3. /time/0 calls should detect closed session, recreate it, and eventually succeed
510511 """
511512 handler = self ._make_handler ()
513+ original_session = handler ._ensure_session ()
512514
513515 # Step 1: Watchdog closes the session
514- handler . session .close ()
515- self .assertTrue (handler .session .is_closed )
516+ original_session .close ()
517+ self .assertTrue (handler ._session .is_closed )
516518
517519 from pubnub .structures import RequestOptions , PlatformOptions
518520 p_options = MagicMock (spec = PlatformOptions )
@@ -540,21 +542,22 @@ def test_reconnection_time_request_works_after_session_close(self):
540542 # Should be a connection error, NOT "Cannot send a request, as the client has been closed"
541543 self .assertNotIn ("client has been closed" , str (e ).lower ())
542544
543- self .assertFalse (handler .session .is_closed )
545+ self .assertFalse (handler ._session .is_closed )
544546 handler .close ()
545547
546548
547549class TestWallClockErrorCategory (unittest .TestCase ):
548- """Tests that wall-clock sleep timeouts produce PNUnexpectedDisconnectCategory,
549- not PNTimeoutCategory — so they route through the reconnection manager with
550- configured retry delays instead of an immediate silent restart.
550+ """Tests that wall-clock sleep timeouts produce PNTimeoutCategory,
551+ so they silently restart the subscribe loop. If the network is actually
552+ down, the next request will fail with a real connection error that routes
553+ through the reconnection manager with configured retry delays.
551554 """
552555
553- def test_watchdog_triggered_produces_connection_error (self ):
554- """When watchdog triggers during a request, the exception should use PNERR_CONNECTION_ERROR
555- which maps to PNUnexpectedDisconnectCategory in _build_envelope."""
556+ def test_watchdog_triggered_produces_timeout_error (self ):
557+ """When watchdog triggers during a request, the exception should use PNERR_CLIENT_TIMEOUT
558+ which maps to PNTimeoutCategory in _build_envelope."""
556559 from pubnub .request_handlers .httpx import HttpxRequestHandler
557- from pubnub .errors import PNERR_CONNECTION_ERROR
560+ from pubnub .errors import PNERR_CLIENT_TIMEOUT
558561 from pubnub .exceptions import PubNubException
559562 from pubnub .structures import RequestOptions , PlatformOptions
560563
@@ -565,7 +568,7 @@ def test_watchdog_triggered_produces_connection_error(self):
565568 mock_session = MagicMock (spec = httpx .Client )
566569 mock_session .is_closed = False
567570 mock_session .request .side_effect = httpx .ReadTimeout ("timed out" )
568- handler .session = mock_session
571+ handler ._session = mock_session
569572
570573 # Mock watchdog.triggered to return True (simulates watchdog firing during request)
571574 type(handler ._watchdog ).triggered = property (lambda self : True )
@@ -590,10 +593,8 @@ def test_watchdog_triggered_produces_connection_error(self):
590593 with self .assertRaises (PubNubException ) as ctx :
591594 handler ._invoke_request (p_options , e_options , 'ps.pndsn.com' )
592595
593- self .assertEqual (ctx .exception ._pn_error , PNERR_CONNECTION_ERROR )
596+ self .assertEqual (ctx .exception ._pn_error , PNERR_CLIENT_TIMEOUT )
594597 self .assertIn ("Wall-clock deadline exceeded" , ctx .exception ._errormsg )
595- # Session should have been recreated
596- self .assertIsNot (handler .session , mock_session )
597598
598599 handler ._watchdog .stop ()
599600 handler .close ()
@@ -636,8 +637,8 @@ def mock_time():
636637
637638 asyncio .run (run_test ())
638639
639- def test_async_wall_clock_timeout_maps_to_unexpected_disconnect (self ):
640- """WallClockTimeoutError should produce PNUnexpectedDisconnectCategory in request_future."""
640+ def test_async_wall_clock_timeout_maps_to_timeout_category (self ):
641+ """WallClockTimeoutError should produce PNTimeoutCategory in request_future."""
641642 from pubnub .request_handlers .async_httpx import WallClockTimeoutError
642643 from pubnub .pubnub_asyncio import PubNubAsyncio
643644 from pubnub .pnconfiguration import PNConfiguration
@@ -668,7 +669,7 @@ def options_func():
668669 self .assertTrue (result .is_error ())
669670 self .assertEqual (
670671 result .status .category ,
671- PNStatusCategory .PNUnexpectedDisconnectCategory
672+ PNStatusCategory .PNTimeoutCategory
672673 )
673674 finally :
674675 await pubnub .stop ()
0 commit comments