diff --git a/packages/agents-a365-tooling-extensions-openai/src/McpToolRegistrationService.ts b/packages/agents-a365-tooling-extensions-openai/src/McpToolRegistrationService.ts index e6edb0e4..a35562c4 100644 --- a/packages/agents-a365-tooling-extensions-openai/src/McpToolRegistrationService.ts +++ b/packages/agents-a365-tooling-extensions-openai/src/McpToolRegistrationService.ts @@ -174,8 +174,15 @@ export class McpToolRegistrationService { orchestratorName: toolOptions?.orchestratorName ?? this.orchestratorName }; - // Convert OpenAI messages to ChatHistoryMessage format - const chatHistoryMessages = this.convertToChatHistoryMessages(messages); + let chatHistoryMessages: ChatHistoryMessage[]; + try { + // Convert OpenAI messages to ChatHistoryMessage format + chatHistoryMessages = this.convertToChatHistoryMessages(messages); + } catch (err: unknown) { + // Convert errors from message conversion into a failed OperationResult + const error = err instanceof Error ? err : new Error(String(err)); + return OperationResult.failed(new OperationError(error)); + } // Delegate to core service return await this.configService.sendChatHistory( diff --git a/tests/tooling-extensions-openai/sendChatHistoryMessagesAsync.test.ts b/tests/tooling-extensions-openai/sendChatHistoryMessagesAsync.test.ts index 16acf680..633ad405 100644 --- a/tests/tooling-extensions-openai/sendChatHistoryMessagesAsync.test.ts +++ b/tests/tooling-extensions-openai/sendChatHistoryMessagesAsync.test.ts @@ -242,6 +242,36 @@ describe('McpToolRegistrationService - sendChatHistoryMessagesAsync', () => { expect(result.errors).toHaveLength(1); }); + it('EH-05: should return failed when message conversion throws unexpected error', async () => { + const messages = createMixedMessages(); + + // Mock convertToChatHistoryMessages to throw an error + jest.spyOn(service as any, 'convertToChatHistoryMessages').mockImplementation(() => { + throw new Error('Conversion error'); + }); + + const result = await service.sendChatHistoryMessagesAsync(mockTurnContext, messages); + + expect(result.succeeded).toBe(false); + expect(result.errors).toHaveLength(1); + expect(result.errors[0].message).toBe('Conversion error'); + }); + + it('EH-06: should handle non-Error thrown values gracefully', async () => { + const messages = createMixedMessages(); + + // Mock convertToChatHistoryMessages to throw a non-Error object + jest.spyOn(service as any, 'convertToChatHistoryMessages').mockImplementation(() => { + throw 'String error'; // eslint-disable-line no-throw-literal + }); + + const result = await service.sendChatHistoryMessagesAsync(mockTurnContext, messages); + + expect(result.succeeded).toBe(false); + expect(result.errors).toHaveLength(1); + expect(result.errors[0].message).toBe('String error'); + }); + it('should re-throw validation errors from core service', async () => { const messages = createMixedMessages(); // Remove conversation ID to trigger validation error