From ef74dcc41f19aa8410bcc610408e8710de56291c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 Aug 2025 16:26:54 +0000 Subject: [PATCH 1/2] Initial plan From 2340dccde4ad1194748ca37509f0855f5e189797 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 1 Aug 2025 16:39:50 +0000 Subject: [PATCH 2/2] Fix simulator errors when sending message after flow completes Co-authored-by: rowanseymour <675558+rowanseymour@users.noreply.github.com> --- src/components/simulator/Simulator.test.ts | 127 ++++++++++++++++++++- src/components/simulator/Simulator.tsx | 13 ++- 2 files changed, 136 insertions(+), 4 deletions(-) diff --git a/src/components/simulator/Simulator.test.ts b/src/components/simulator/Simulator.test.ts index 55d7c3a39..caee489dd 100644 --- a/src/components/simulator/Simulator.test.ts +++ b/src/components/simulator/Simulator.test.ts @@ -16,7 +16,8 @@ const { setup } = composeComponentTestUtils(Simulator, { }, liveActivity: null, mergeEditorState: jest.fn(), - language: null + onToggled: jest.fn(), + popped: '' }); describe(Simulator.name, () => { @@ -24,4 +25,128 @@ describe(Simulator.name, () => { const { wrapper } = setup(); expect(wrapper).toMatchSnapshot(); }); + + describe('updateRunContext edge cases', () => { + it('handles null events array in runContext', () => { + const { instance } = setup(); + const simulator = instance as any; + + // Create a partial mock to test just the problematic code path + const runContext = { + contact: { uuid: 'test', urns: [], status: 'active', fields: {}, groups: [], created_on: '2020-01-01T00:00:00Z' }, + session: { runs: [], contact: null, status: 'completed' }, + context: {}, + events: null, // This should cause the unshift error + segments: [] + }; + + const msgEvt = { uuid: 'test', type: 'msg_received', created_on: new Date().toISOString() }; + + // Mock setState and other dependencies to isolate the test + simulator.setState = jest.fn((newState, callback) => { + if (callback) callback(); + }); + simulator.updateEvents = jest.fn((events, session, callback) => callback()); + simulator.updateActivity = jest.fn(); + simulator.handleFocusUpdate = jest.fn(); + + // This should not throw when events is null + expect(() => { + simulator.updateRunContext(runContext, msgEvt); + }).not.toThrow(); + }); + + it('handles undefined events array in runContext', () => { + const { instance } = setup(); + const simulator = instance as any; + + const runContext = { + contact: { uuid: 'test', urns: [], status: 'active', fields: {}, groups: [], created_on: '2020-01-01T00:00:00Z' }, + session: { runs: [], contact: null, status: 'completed' }, + context: {}, + events: undefined, // This should cause the unshift error + segments: [] + }; + + const msgEvt = { uuid: 'test', type: 'msg_received', created_on: new Date().toISOString() }; + + // Mock setState and other dependencies to isolate the test + simulator.setState = jest.fn((newState, callback) => { + if (callback) callback(); + }); + simulator.updateEvents = jest.fn((events, session, callback) => callback()); + simulator.updateActivity = jest.fn(); + simulator.handleFocusUpdate = jest.fn(); + + // This should not throw when events is undefined + expect(() => { + simulator.updateRunContext(runContext, msgEvt); + }).not.toThrow(); + }); + }); + + describe('resume error handling', () => { + it('handles error without response object', () => { + const { instance } = setup(); + const simulator = instance as any; + + // Mock setState to avoid component lifecycle issues + simulator.setState = jest.fn(); + simulator.state = { events: [] }; + + // Create an error without response (network error) + const error = new Error('Network error'); + // Don't set error.response - this should cause the error on line 521 + + // Test the catch block in resume method - simulate the actual catch logic + const catchHandler = (error: any) => { + if (error.response && error.response.status) { + // Condition check + } + const errorText = error.response && error.response.status > 499 + ? 'Server error, try again later' + : error.response && error.response.data && error.response.data.error + ? error.response.data.error + : 'An error occurred'; + + return errorText; + }; + + // This should not throw when error.response is undefined + expect(() => { + const result = catchHandler(error); + expect(result).toBe('An error occurred'); + }).not.toThrow(); + }); + + it('handles error with response but no data', () => { + const { instance } = setup(); + const simulator = instance as any; + + simulator.setState = jest.fn(); + simulator.state = { events: [] }; + + // Create an error with response but no data + const error = new Error('Server error'); + (error as any).response = { status: 500 }; + + const catchHandler = (error: any) => { + if (error.response && error.response.status) { + // Condition check + } + const errorText = error.response && error.response.status > 499 + ? 'Server error, try again later' + : error.response && error.response.data && error.response.data.error + ? error.response.data.error + : 'An error occurred'; + + return errorText; + }; + + expect(() => { + const result = catchHandler(error); + expect(result).toBe('Server error, try again later'); + }).not.toThrow(); + }); + }); }); diff --git a/src/components/simulator/Simulator.tsx b/src/components/simulator/Simulator.tsx index e37bd5921..da2334ac6 100644 --- a/src/components/simulator/Simulator.tsx +++ b/src/components/simulator/Simulator.tsx @@ -325,6 +325,11 @@ export class Simulator extends React.Component { } private updateRunContext(runContext: RunContext, msgEvt?: any): void { + // Ensure events is always an array to prevent null/undefined errors + if (!runContext.events) { + runContext.events = []; + } + const wasJustActive = this.state.active || (runContext.events && runContext.events.length > 0); this.setState({ quickReplies: [] }, () => { // if session is waiting, find the wait event @@ -518,16 +523,18 @@ export class Simulator extends React.Component { this.updateRunContext(response.data as RunContext, msgInEvt); }) .catch(error => { - if (error.response.status) { + if (error.response && error.response.status) { } const events = update(this.state.events, { $push: [ { type: 'error', text: - error.response.status > 499 + error.response && error.response.status > 499 ? 'Server error, try again later' - : error.response.data.error + : error.response && error.response.data && error.response.data.error + ? error.response.data.error + : 'An error occurred' } as any ] }) as EventProps[];