Skip to content

Commit 813fcc3

Browse files
committed
Add defensive error handling to prevent exit code 1 on Windows
- downloader.py: wrap canvasapi/requests/tqdm imports in try/except; guard CANVAS_URL/CANVAS_TOKEN before use; wrap Canvas() ctor in try/except - semantic_alignment.py: wrap faiss/numpy top-level imports in try/except - note_generation.py: wrap tqdm/alignment_parser imports in try/except - electron/main.js: pre-flight check Python exe and script file existence before spawning; upgrade pipe-mode error handler to show actionable hint on ENOENT (python not found)
1 parent 8a84933 commit 813fcc3

4 files changed

Lines changed: 71 additions & 10 deletions

File tree

downloader.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,14 @@
2929
from datetime import datetime, timezone
3030
from pathlib import Path
3131

32-
import requests
33-
from canvasapi import Canvas
34-
from tqdm import tqdm
32+
try:
33+
import requests
34+
from canvasapi import Canvas
35+
from tqdm import tqdm
36+
except ImportError as _e:
37+
print(f"[error] Missing dependency: {_e}")
38+
print("[error] Please install the ML environment from Settings → ML Environment in the AutoNote app.")
39+
sys.exit(1)
3540

3641
# ── Configuration ──────────────────────────────────────────────────────────────
3742

@@ -1059,8 +1064,21 @@ def main() -> None:
10591064
parser.print_help()
10601065
sys.exit(0)
10611066

1067+
if not CANVAS_URL:
1068+
print("[error] Canvas URL is not configured.")
1069+
print("[error] Enter your Canvas URL in Settings → Connection in the AutoNote app.")
1070+
sys.exit(1)
1071+
if not CANVAS_TOKEN:
1072+
print("[error] Canvas token is not configured.")
1073+
print("[error] Enter your Canvas API token in Settings → API Keys in the AutoNote app.")
1074+
sys.exit(1)
1075+
10621076
base_dir = Path(args.path) if args.path else DATA_DIR
1063-
canvas = Canvas(CANVAS_URL, CANVAS_TOKEN)
1077+
try:
1078+
canvas = Canvas(CANVAS_URL, CANVAS_TOKEN)
1079+
except Exception as e:
1080+
print(f"[error] Failed to connect to Canvas: {e}")
1081+
sys.exit(1)
10641082

10651083
# ── --course-list ──────────────────────────────────────────────────────────
10661084
if args.course_list:

electron/main.js

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,9 +342,33 @@ let installProc = null;
342342
let mainWindow = null;
343343

344344
// ── Subprocess runner (pipeline scripts) ─────────────────────────────────────
345+
function sendProcessError(msg) {
346+
mainWindow?.webContents.send('process:data', msg + '\n');
347+
mainWindow?.webContents.send('process:done', { code: 1 });
348+
}
349+
345350
function runProcess(cmd) {
346351
if (activeProc) return { error: 'Already running — stop it first.' };
347352

353+
// ── Pre-flight validation ──────────────────────────────────────────────────
354+
const [pythonExe, scriptFile] = cmd;
355+
356+
// Validate Python executable: if it looks like an absolute path, check it exists.
357+
if (pythonExe && path.isAbsolute(pythonExe) && !fs.existsSync(pythonExe)) {
358+
sendProcessError(
359+
`[error] Python executable not found: ${pythonExe}\n` +
360+
`[error] Please install the ML environment from Settings → ML Environment,\n` +
361+
`[error] or configure a valid Python path in Settings → Connection.`
362+
);
363+
return { ok: true };
364+
}
365+
366+
// Validate script file exists.
367+
if (scriptFile && path.isAbsolute(scriptFile) && !fs.existsSync(scriptFile)) {
368+
sendProcessError(`[error] Script not found: ${scriptFile}`);
369+
return { ok: true };
370+
}
371+
348372
const outDir = getOutputDir();
349373
fs.mkdirSync(outDir, { recursive: true });
350374
const env = {
@@ -393,7 +417,11 @@ function runProcess(cmd) {
393417
});
394418
proc.on('error', err => {
395419
activeProc = null;
396-
mainWindow?.webContents.send('process:done', { code: -1, error: err.message });
420+
const hint = err.code === 'ENOENT'
421+
? `\n[error] Could not find executable: ${prog}\n[error] Install the ML environment from Settings → ML Environment.`
422+
: '';
423+
mainWindow?.webContents.send('process:data', `[error] ${err.message}${hint}\n`);
424+
mainWindow?.webContents.send('process:done', { code: 1 });
397425
});
398426
return { ok: true };
399427
}

note_generation.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,19 @@
2525
from datetime import datetime
2626
from pathlib import Path
2727

28-
from tqdm import tqdm
29-
30-
import alignment_parser
28+
try:
29+
from tqdm import tqdm
30+
except ImportError as _e:
31+
print(f"[error] Missing dependency: {_e}")
32+
print("[error] Please install the ML environment from Settings → ML Environment in the AutoNote app.")
33+
sys.exit(1)
34+
35+
try:
36+
import alignment_parser
37+
except ImportError as _e:
38+
print(f"[error] Could not import alignment_parser: {_e}")
39+
print(f"[error] Make sure alignment_parser.py is in the same directory as note_generation.py")
40+
sys.exit(1)
3141

3242
PROJECT_DIR = Path(__file__).parent
3343
import sys as _sys

semantic_alignment.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,13 @@
3535
from pathlib import Path
3636
from typing import NamedTuple
3737

38-
import faiss
39-
import numpy as np
38+
try:
39+
import faiss
40+
import numpy as np
41+
except ImportError as _e:
42+
print(f"[error] Missing dependency: {_e}")
43+
print("[error] Please install the ML environment from Settings → ML Environment in the AutoNote app.")
44+
sys.exit(1)
4045

4146
PROJECT_DIR = Path(__file__).parent
4247
import sys as _sys

0 commit comments

Comments
 (0)