Skip to content

Commit b0ea642

Browse files
nodeeeeeeclaude
andcommitted
Fix smart match empty output: replace async spawn with spawnSync
The async spawn() had a race condition where the 'close' event fired before all stdout/stderr data was collected, resulting in "(empty)" output. Replaced with spawnSync() which guarantees all output is captured before returning. Also logs the exact command being run. Bumped to v0.9.28 for fresh AppImage filename. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 540b046 commit b0ea642

2 files changed

Lines changed: 36 additions & 42 deletions

File tree

electron/main.js

Lines changed: 35 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,49 +1034,43 @@ function registerIpc() {
10341034
}
10351035
}
10361036

1037-
// Run the actual matching script
1038-
const cmd = [python, script, '--course', String(cid),
1039-
'--suggest-matches', '--match-model', model || 'bge-m3'];
1037+
// Run the actual matching script (synchronous — takes a few seconds)
1038+
const args = [script, '--course', String(cid),
1039+
'--suggest-matches', '--match-model', model || 'bge-m3'];
1040+
diagLines.push(`Command: ${python} ${args.join(' ')}`);
1041+
const diagStr2 = diagLines.join('\n');
10401042

1041-
return new Promise((resolve) => {
1042-
let proc;
1043-
try {
1044-
proc = spawn(cmd[0], cmd.slice(1), {
1045-
env: { ...process.env, AUTONOTE_DATA_DIR: DATA_DIR },
1046-
stdio: ['ignore', 'pipe', 'pipe'],
1047-
});
1048-
} catch (e) {
1049-
resolve({ __error: `Failed to spawn process: ${e.message}\n\n${diagStr}` });
1050-
return;
1051-
}
1052-
let stdout = '';
1053-
let stderr = '';
1054-
proc.stdout.on('data', d => { stdout += d.toString(); });
1055-
proc.stderr.on('data', d => { stderr += d.toString(); });
1056-
proc.on('error', (e) => {
1057-
resolve({ __error: `Process error: ${e.message}\n\n${diagStr}` });
1058-
});
1059-
proc.on('close', (code) => {
1060-
const combined = stdout + '\n' + stderr;
1061-
if (code !== 0) {
1062-
resolve({ __error: `Exit code ${code}:\n${combined.trim()}\n\n── Diagnostics ──\n${diagStr}` });
1063-
return;
1064-
}
1065-
const marker = '__MATCH_RESULT__';
1066-
const idx = combined.indexOf(marker);
1067-
if (idx < 0) {
1068-
resolve({ __error: `No results marker in output:\n${combined.trim()}\n\n── Diagnostics ──\n${diagStr}` });
1069-
return;
1070-
}
1071-
try {
1072-
const result = JSON.parse(combined.slice(idx + marker.length).trim());
1073-
result.__log = combined.slice(0, idx).trim();
1074-
resolve(result);
1075-
} catch (e) {
1076-
resolve({ __error: `JSON parse error: ${e.message}\n${combined.trim()}` });
1077-
}
1043+
let result;
1044+
try {
1045+
result = spawnSync(python, args, {
1046+
encoding: 'utf8',
1047+
timeout: 120000, // 2 minutes max
1048+
env: { ...process.env, AUTONOTE_DATA_DIR: DATA_DIR },
1049+
stdio: ['ignore', 'pipe', 'pipe'],
10781050
});
1079-
});
1051+
} catch (e) {
1052+
return { __error: `Failed to run: ${e.message}\n\n── Diagnostics ──\n${diagStr2}` };
1053+
}
1054+
1055+
const combined = (result.stdout || '') + '\n' + (result.stderr || '');
1056+
1057+
if (result.status !== 0) {
1058+
return { __error: `Exit code ${result.status}:\n${combined.trim()}\n\n── Diagnostics ──\n${diagStr2}` };
1059+
}
1060+
1061+
const marker = '__MATCH_RESULT__';
1062+
const idx = combined.indexOf(marker);
1063+
if (idx < 0) {
1064+
return { __error: `No results in output:\n${combined.trim()}\n\n── Diagnostics ──\n${diagStr2}` };
1065+
}
1066+
1067+
try {
1068+
const parsed = JSON.parse(combined.slice(idx + marker.length).trim());
1069+
parsed.__log = combined.slice(0, idx).trim();
1070+
return parsed;
1071+
} catch (e) {
1072+
return { __error: `JSON parse error: ${e.message}\n${combined.trim()}` };
1073+
}
10801074
});
10811075

10821076
ipcMain.handle('align:saveMapping', (_, { cid, mapping }) => {

electron/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "auto-note",
3-
"version": "0.9.27",
3+
"version": "0.9.28",
44
"description": "AutoNote — lecture notes generator from Canvas recordings",
55
"homepage": "https://github.com/nodeeeeee/Auto-Note",
66
"author": {

0 commit comments

Comments
 (0)