From 640f50d525bdd41dc1396b63bfbf38a7e50bb8c0 Mon Sep 17 00:00:00 2001 From: Rohit Malhotra Date: Fri, 17 Oct 2025 14:12:18 -0400 Subject: [PATCH] Fix: exception handling for get convo metadata (#11421) --- enterprise/integrations/jira/jira_view.py | 6 ++++-- enterprise/integrations/jira_dc/jira_dc_view.py | 6 ++++-- enterprise/integrations/linear/linear_view.py | 6 ++++-- enterprise/integrations/slack/slack_view.py | 6 ++++-- .../tests/unit/integrations/jira/test_jira_view.py | 4 +++- .../unit/integrations/jira_dc/test_jira_dc_view.py | 4 +++- .../unit/integrations/linear/test_linear_view.py | 4 +++- openhands/server/services/conversation_service.py | 14 +++----------- 8 files changed, 28 insertions(+), 22 deletions(-) diff --git a/enterprise/integrations/jira/jira_view.py b/enterprise/integrations/jira/jira_view.py index 1cc1e71046..eeff968ec3 100644 --- a/enterprise/integrations/jira/jira_view.py +++ b/enterprise/integrations/jira/jira_view.py @@ -132,8 +132,10 @@ class JiraExistingConversationView(JiraViewInterface): conversation_store = await ConversationStoreImpl.get_instance( config, user_id ) - metadata = await conversation_store.get_metadata(self.conversation_id) - if not metadata: + + try: + await conversation_store.get_metadata(self.conversation_id) + except FileNotFoundError: raise StartingConvoException('Conversation no longer exists.') provider_tokens = await self.saas_user_auth.get_provider_tokens() diff --git a/enterprise/integrations/jira_dc/jira_dc_view.py b/enterprise/integrations/jira_dc/jira_dc_view.py index 907d83bcd4..c60cbfc982 100644 --- a/enterprise/integrations/jira_dc/jira_dc_view.py +++ b/enterprise/integrations/jira_dc/jira_dc_view.py @@ -135,8 +135,10 @@ class JiraDcExistingConversationView(JiraDcViewInterface): conversation_store = await ConversationStoreImpl.get_instance( config, user_id ) - metadata = await conversation_store.get_metadata(self.conversation_id) - if not metadata: + + try: + await conversation_store.get_metadata(self.conversation_id) + except FileNotFoundError: raise StartingConvoException('Conversation no longer exists.') provider_tokens = await self.saas_user_auth.get_provider_tokens() diff --git a/enterprise/integrations/linear/linear_view.py b/enterprise/integrations/linear/linear_view.py index c2c0292f53..a0cf69a5f8 100644 --- a/enterprise/integrations/linear/linear_view.py +++ b/enterprise/integrations/linear/linear_view.py @@ -132,8 +132,10 @@ class LinearExistingConversationView(LinearViewInterface): conversation_store = await ConversationStoreImpl.get_instance( config, user_id ) - metadata = await conversation_store.get_metadata(self.conversation_id) - if not metadata: + + try: + await conversation_store.get_metadata(self.conversation_id) + except FileNotFoundError: raise StartingConvoException('Conversation no longer exists.') provider_tokens = await self.saas_user_auth.get_provider_tokens() diff --git a/enterprise/integrations/slack/slack_view.py b/enterprise/integrations/slack/slack_view.py index 4c5bc00ced..fdaed07971 100644 --- a/enterprise/integrations/slack/slack_view.py +++ b/enterprise/integrations/slack/slack_view.py @@ -263,8 +263,10 @@ class SlackUpdateExistingConversationView(SlackNewConversationView): # Check if conversation has been deleted # Update logic when soft delete is implemented conversation_store = await ConversationStoreImpl.get_instance(config, user_id) - metadata = await conversation_store.get_metadata(self.conversation_id) - if not metadata: + + try: + await conversation_store.get_metadata(self.conversation_id) + except FileNotFoundError: raise StartingConvoException('Conversation no longer exists.') provider_tokens = await saas_user_auth.get_provider_tokens() diff --git a/enterprise/tests/unit/integrations/jira/test_jira_view.py b/enterprise/tests/unit/integrations/jira/test_jira_view.py index 0fcdcd8afa..07b885f59d 100644 --- a/enterprise/tests/unit/integrations/jira/test_jira_view.py +++ b/enterprise/tests/unit/integrations/jira/test_jira_view.py @@ -137,7 +137,9 @@ class TestJiraExistingConversationView: ): """Test conversation update with no metadata""" mock_store = AsyncMock() - mock_store.get_metadata.return_value = None + mock_store.get_metadata.side_effect = FileNotFoundError( + 'No such file or directory' + ) mock_store_impl.return_value = mock_store with pytest.raises( diff --git a/enterprise/tests/unit/integrations/jira_dc/test_jira_dc_view.py b/enterprise/tests/unit/integrations/jira_dc/test_jira_dc_view.py index 3efb616a62..bd1f1f352e 100644 --- a/enterprise/tests/unit/integrations/jira_dc/test_jira_dc_view.py +++ b/enterprise/tests/unit/integrations/jira_dc/test_jira_dc_view.py @@ -137,7 +137,9 @@ class TestJiraDcExistingConversationView: ): """Test conversation update with no metadata""" mock_store = AsyncMock() - mock_store.get_metadata.return_value = None + mock_store.get_metadata.side_effect = FileNotFoundError( + 'No such file or directory' + ) mock_store_impl.return_value = mock_store with pytest.raises( diff --git a/enterprise/tests/unit/integrations/linear/test_linear_view.py b/enterprise/tests/unit/integrations/linear/test_linear_view.py index 67acf720f0..dc410a9a5c 100644 --- a/enterprise/tests/unit/integrations/linear/test_linear_view.py +++ b/enterprise/tests/unit/integrations/linear/test_linear_view.py @@ -137,7 +137,9 @@ class TestLinearExistingConversationView: ): """Test conversation update with no metadata""" mock_store = AsyncMock() - mock_store.get_metadata.return_value = None + mock_store.get_metadata.side_effect = FileNotFoundError( + 'No such file or directory' + ) mock_store_impl.return_value = mock_store with pytest.raises( diff --git a/openhands/server/services/conversation_service.py b/openhands/server/services/conversation_service.py index 407c351b2f..2b0f61ee55 100644 --- a/openhands/server/services/conversation_service.py +++ b/openhands/server/services/conversation_service.py @@ -38,7 +38,7 @@ async def initialize_conversation( selected_branch: str | None, conversation_trigger: ConversationTrigger = ConversationTrigger.GUI, git_provider: ProviderType | None = None, -) -> ConversationMetadata | None: +) -> ConversationMetadata: if conversation_id is None: conversation_id = uuid.uuid4().hex @@ -66,13 +66,8 @@ async def initialize_conversation( await conversation_store.save_metadata(conversation_metadata) return conversation_metadata - try: - conversation_metadata = await conversation_store.get_metadata(conversation_id) - return conversation_metadata - except Exception: - pass - - return None + conversation_metadata = await conversation_store.get_metadata(conversation_id) + return conversation_metadata async def start_conversation( @@ -190,9 +185,6 @@ async def create_new_conversation( git_provider, ) - if not conversation_metadata: - raise Exception('Failed to initialize conversation') - return await start_conversation( user_id, git_provider_tokens,