Skip to content

Commit 1671fc9

Browse files
Include exit code when evaluation process terminates abruptly (#46)
Also optimises stdout/stderr accumulation to avoid intermediate strings.
1 parent 384e5b1 commit 1671fc9

2 files changed

Lines changed: 22 additions & 19 deletions

File tree

src/evaluation/code_executor.ts

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,37 +12,40 @@ export async function executeIsolated(request: EvaluationRequest): Promise<Evalu
1212

1313
const child = fork(workerPath, { silent: true });
1414

15-
const evaluation: EvaluatedModuleResult = {
16-
success: false,
17-
result: null,
18-
stdout: '',
19-
stderr: '',
20-
};
15+
let result: { success: boolean; result: string | null } | null = null;
16+
const stdoutChunks: string[] = [];
17+
const stderrChunks: string[] = [];
2118

2219
child.stdout?.on('data', data => {
23-
evaluation.stdout += data.toString();
20+
stdoutChunks.push(data.toString());
2421
});
2522

2623
child.stderr?.on('data', data => {
27-
evaluation.stderr += data.toString();
24+
stderrChunks.push(data.toString());
2825
});
2926

3027
child.on('message', (msg: { type: 'result'; data: string; success: boolean }) => {
3128
if (msg.type === 'result') {
3229
const { data, success } = msg;
33-
evaluation.result = data;
34-
evaluation.success = success;
30+
result = { success, result: data };
3531
// Acknowledge the result and tell the child to exit gracefully.
3632
child.send({ type: 'finish' });
3733
}
3834
});
3935

4036
child.on('exit', code => {
37+
if (result === null) {
38+
result = {
39+
success: false,
40+
result: `Evaluation process terminated unexpectedly with code ${code}`,
41+
};
42+
}
43+
4144
resolve({
42-
success: evaluation.success && code === 0,
43-
result: evaluation.result,
44-
stdout: evaluation.stdout.trim(),
45-
stderr: evaluation.stderr.trim(),
45+
success: result.success,
46+
result: result.result,
47+
stdout: stdoutChunks.join(''),
48+
stderr: stderrChunks.join(''),
4649
} as EvaluatedModuleResult);
4750
});
4851

@@ -53,8 +56,8 @@ export async function executeIsolated(request: EvaluationRequest): Promise<Evalu
5356
resolve({
5457
success: false,
5558
result: `Evaluation timed out after ${timeout} milliseconds`,
56-
stdout: evaluation.stdout,
57-
stderr: evaluation.stderr,
59+
stdout: stdoutChunks.join(''),
60+
stderr: stderrChunks.join(''),
5861
} as EvaluatedModuleResult);
5962
}, timeout);
6063

test/integration.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ describe('Project scoped evaluation', () => {
239239
expect(result.success).toBe(true);
240240
expect(result.stderr).toBeFalsy();
241241
expect(result.result).toBe(null);
242-
expect(result.stdout).toBe('hello, world!');
242+
expect(result.stdout).toBe('hello, world!\n');
243243
});
244244

245245
it('should fork the process and return a custom result', async () => {
@@ -255,7 +255,7 @@ describe('Project scoped evaluation', () => {
255255
const result = await Tidewave.executeIsolated(request);
256256
expect(result.success).toBe(true);
257257
expect(result.stderr).toBeFalsy();
258-
expect(result.stdout).toBe('hello, world!');
258+
expect(result.stdout).toBe('hello, world!\n');
259259
expect(result.result).toBe(42);
260260
});
261261

@@ -287,7 +287,7 @@ describe('Project scoped evaluation', () => {
287287
const result = await Tidewave.executeIsolated(request);
288288
expect(result.success).toBe(true);
289289
expect(result.stderr).toBeFalsy();
290-
expect(result.stdout).toBe('Code is: 42');
290+
expect(result.stdout).toBe('Code is: 42\n');
291291
expect(result.result).toBe(43);
292292
});
293293

0 commit comments

Comments
 (0)