Updates error handling in case of incorrect tool calling. (#2304)

This commit is contained in:
Vachan 2025-06-27 16:57:40 -07:00 committed by GitHub
parent 150df382f8
commit db115c468a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 71 additions and 1 deletions

View File

@ -218,4 +218,69 @@ describe('runNonInteractive', () => {
'[API Error: API connection failed]',
);
});
it('should not exit if a tool is not found, and should send error back to model', async () => {
const functionCall: FunctionCall = {
id: 'fcNotFound',
name: 'nonExistentTool',
args: {},
};
const errorResponsePart: Part = {
functionResponse: {
name: 'nonExistentTool',
id: 'fcNotFound',
response: { error: 'Tool "nonExistentTool" not found in registry.' },
},
};
const { executeToolCall: mockCoreExecuteToolCall } = await import(
'@google/gemini-cli-core'
);
vi.mocked(mockCoreExecuteToolCall).mockResolvedValue({
callId: 'fcNotFound',
responseParts: [errorResponsePart],
resultDisplay: 'Tool "nonExistentTool" not found in registry.',
error: new Error('Tool "nonExistentTool" not found in registry.'),
});
const stream1 = (async function* () {
yield { functionCalls: [functionCall] } as GenerateContentResponse;
})();
const stream2 = (async function* () {
yield {
candidates: [
{
content: {
parts: [{ text: 'Unfortunately the tool does not exist.' }],
},
},
],
} as GenerateContentResponse;
})();
mockChat.sendMessageStream
.mockResolvedValueOnce(stream1)
.mockResolvedValueOnce(stream2);
const consoleErrorSpy = vi
.spyOn(console, 'error')
.mockImplementation(() => {});
await runNonInteractive(mockConfig, 'Trigger tool not found');
expect(consoleErrorSpy).toHaveBeenCalledWith(
'Error executing tool nonExistentTool: Tool "nonExistentTool" not found in registry.',
);
expect(mockProcessExit).not.toHaveBeenCalled();
expect(mockChat.sendMessageStream).toHaveBeenCalledTimes(2);
expect(mockChat.sendMessageStream).toHaveBeenLastCalledWith(
expect.objectContaining({
message: [errorResponsePart],
}),
);
expect(mockProcessStdoutWrite).toHaveBeenCalledWith(
'Unfortunately the tool does not exist.',
);
});
});

View File

@ -110,10 +110,15 @@ export async function runNonInteractive(
);
if (toolResponse.error) {
const isToolNotFound = toolResponse.error.message.includes(
'not found in registry',
);
console.error(
`Error executing tool ${fc.name}: ${toolResponse.resultDisplay || toolResponse.error.message}`,
);
process.exit(1);
if (!isToolNotFound) {
process.exit(1);
}
}
if (toolResponse.responseParts) {