Skip to content

Commit e32746f

Browse files
committed
fix: retry read-only in-flight runner commands
1 parent 8db2910 commit e32746f

2 files changed

Lines changed: 21 additions & 0 deletions

File tree

src/platforms/ios/__tests__/runner-command-retry.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,24 @@ test('read-only commands retry when completed status has no retained response',
213213
assert.equal(mockExecuteRunnerCommandWithSession.mock.calls[2]?.[2].command, 'snapshot');
214214
});
215215

216+
test('read-only commands retry when status shows in-flight work', async () => {
217+
const session = makeRunnerSession({ port: 8100, ready: true });
218+
219+
mockEnsureRunnerSession.mockResolvedValue(session);
220+
mockExecuteRunnerCommandWithSession
221+
.mockRejectedValueOnce(new AppError('COMMAND_FAILED', 'fetch failed'))
222+
.mockResolvedValueOnce({ lifecycleState: 'started' })
223+
.mockResolvedValueOnce({ nodes: [], truncated: false });
224+
225+
const result = await runIosRunnerCommand(IOS_SIMULATOR, { command: 'snapshot' });
226+
227+
assert.deepEqual(result, { nodes: [], truncated: false });
228+
assert.equal(mockInvalidateRunnerSession.mock.calls.length, 0);
229+
assert.equal(mockExecuteRunnerCommandWithSession.mock.calls.length, 3);
230+
assert.equal(mockExecuteRunnerCommandWithSession.mock.calls[1]?.[2].command, 'status');
231+
assert.equal(mockExecuteRunnerCommandWithSession.mock.calls[2]?.[2].command, 'snapshot');
232+
});
233+
216234
test('mutating commands report recovery guidance when completed status has no retained response', async () => {
217235
const session = makeRunnerSession({ port: 8100, ready: true });
218236

src/platforms/ios/runner-client.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,9 @@ async function tryRecoverRunnerCommandAfterTransportError(
313313
}
314314

315315
if (lifecycleState === 'accepted' || lifecycleState === 'started') {
316+
if (isReadOnlyRunnerCommand(command.command)) {
317+
throw transportError;
318+
}
316319
throw new AppError(
317320
'COMMAND_FAILED',
318321
`Runner command "${command.command}" is still ${lifecycleState} after the transport response was lost.`,

0 commit comments

Comments
 (0)