mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-08-24 11:07:14 +00:00
fix(box): handle RPC failure in get_status/get_sessions gracefully
When the Box runtime disconnects, there is a race between the heartbeat flipping _available=false and the frontend polling get_status(). If the poll arrives first, client.get_status() throws a ConnectionClosedError which propagated as a 500, causing the frontend to show a grey dot (null status) instead of a red dot with error details. Now get_status() catches RPC errors and returns available=false with the exception message as connector_error. get_sessions() returns an empty list when unavailable or on RPC failure.
This commit is contained in:
@@ -219,7 +219,12 @@ class BoxService:
|
|||||||
self._shutdown_task = loop.create_task(self.shutdown())
|
self._shutdown_task = loop.create_task(self.shutdown())
|
||||||
|
|
||||||
async def get_sessions(self) -> list[dict]:
|
async def get_sessions(self) -> list[dict]:
|
||||||
return await self.client.get_sessions()
|
if not self._available:
|
||||||
|
return []
|
||||||
|
try:
|
||||||
|
return await self.client.get_sessions()
|
||||||
|
except Exception:
|
||||||
|
return []
|
||||||
|
|
||||||
def build_spec(self, spec_payload: dict, skip_host_mount_validation: bool = False) -> BoxSpec:
|
def build_spec(self, spec_payload: dict, skip_host_mount_validation: bool = False) -> BoxSpec:
|
||||||
spec_payload = dict(spec_payload)
|
spec_payload = dict(spec_payload)
|
||||||
@@ -581,7 +586,17 @@ class BoxService:
|
|||||||
'recent_error_count': len(self._recent_errors),
|
'recent_error_count': len(self._recent_errors),
|
||||||
'connector_error': self._connector_error,
|
'connector_error': self._connector_error,
|
||||||
}
|
}
|
||||||
runtime_status = await self.client.get_status()
|
try:
|
||||||
|
runtime_status = await self.client.get_status()
|
||||||
|
except Exception as exc:
|
||||||
|
# RPC failed — the runtime likely just disconnected and the
|
||||||
|
# heartbeat hasn't flipped _available yet.
|
||||||
|
return {
|
||||||
|
'available': False,
|
||||||
|
'profile': self.profile.name,
|
||||||
|
'recent_error_count': len(self._recent_errors),
|
||||||
|
'connector_error': str(exc),
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
**runtime_status,
|
**runtime_status,
|
||||||
'available': True,
|
'available': True,
|
||||||
|
|||||||
@@ -182,6 +182,7 @@ async def test_box_service_get_sessions_delegates_to_client():
|
|||||||
client.get_sessions = AsyncMock(return_value=[{'session_id': 'test-session'}])
|
client.get_sessions = AsyncMock(return_value=[{'session_id': 'test-session'}])
|
||||||
|
|
||||||
service = BoxService(make_app(Mock()), client=client)
|
service = BoxService(make_app(Mock()), client=client)
|
||||||
|
service._available = True
|
||||||
|
|
||||||
sessions = await service.get_sessions()
|
sessions = await service.get_sessions()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user