diff --git a/packages/core/src/core/turn.test.ts b/packages/core/src/core/turn.test.ts index 7144d16b..595de151 100644 --- a/packages/core/src/core/turn.test.ts +++ b/packages/core/src/core/turn.test.ts @@ -445,6 +445,32 @@ describe('Turn', () => { { type: GeminiEventType.Finished, value: 'OTHER' }, ]); }); + + it('should not crash when cancelled request has malformed error', async () => { + const abortController = new AbortController(); + + const errorToThrow = { + response: { + data: undefined, // Malformed error data + }, + }; + + mockSendMessageStream.mockImplementation(async () => { + abortController.abort(); + throw errorToThrow; + }); + + const events = []; + const reqParts: Part[] = [{ text: 'Test malformed error handling' }]; + + for await (const event of turn.run(reqParts, abortController.signal)) { + events.push(event); + } + + expect(events).toEqual([{ type: GeminiEventType.UserCancelled }]); + + expect(reportError).not.toHaveBeenCalled(); + }); }); describe('getDebugResponses', () => { diff --git a/packages/core/src/core/turn.ts b/packages/core/src/core/turn.ts index 8ede1fa4..5f2f017e 100644 --- a/packages/core/src/core/turn.ts +++ b/packages/core/src/core/turn.ts @@ -247,16 +247,17 @@ export class Turn { } } } catch (e) { - const error = toFriendlyError(e); - if (error instanceof UnauthorizedError) { - throw error; - } if (signal.aborted) { yield { type: GeminiEventType.UserCancelled }; // Regular cancellation error, fail gracefully. return; } + const error = toFriendlyError(e); + if (error instanceof UnauthorizedError) { + throw error; + } + const contextForReport = [...this.chat.getHistory(/*curated*/ true), req]; await reportError( error,