4040]
4141
4242
43- def _load_courses_from_canvas () -> None :
44- """Fetch active courses from Canvas and update the global COURSES dict."""
43+ def _load_courses_from_canvas () -> str :
44+ """Fetch active courses from Canvas and update the global COURSES dict.
45+ Returns "" on success, or a human-readable error string on failure."""
4546 COURSES .clear ()
4647 token_file = PROJECT_DIR / "canvas_token.txt"
4748 config_file = PROJECT_DIR / "config.json"
4849 token = token_file .read_text ().strip () if token_file .exists () else ""
4950 if not token :
50- return
51+ return "Canvas token not saved — enter it in Settings → API Keys."
5152 cfg = json .load (open (config_file )) if config_file .exists () else {}
5253 canvas_url = cfg .get ("CANVAS_URL" , "" ).strip ().rstrip ("/" )
5354 if canvas_url and not canvas_url .startswith (("http://" , "https://" )):
5455 canvas_url = "https://" + canvas_url
5556 if not canvas_url :
56- return
57+ return "Canvas URL not saved — enter it in Settings → Connection."
5758 try :
5859 import requests
5960 resp = requests .get (
@@ -70,8 +71,9 @@ def _load_courses_from_canvas() -> None:
7071 if any (kw in name .lower () for kw in _SKIP_KEYWORDS ):
7172 continue
7273 COURSES [c ["id" ]] = name
73- except Exception :
74- pass # silently leave COURSES empty; user sees the empty-state UI
74+ return ""
75+ except Exception as exc :
76+ return str (exc )
7577
7678# ── Palette ───────────────────────────────────────────────────────────────────
7779
@@ -1137,13 +1139,17 @@ def _do_refresh():
11371139 refresh_status .color = ft .Colors .with_opacity (0.6 , ft .Colors .WHITE )
11381140 page .update ()
11391141 # Load courses while this settings page is still attached
1140- _load_courses_from_canvas ()
1142+ err = _load_courses_from_canvas ()
11411143 n = len (COURSES )
1142- refresh_status .value = (
1143- f"✓ { n } course{ 's' if n != 1 else '' } loaded."
1144- if n else "No courses found — check token and Canvas URL."
1145- )
1146- refresh_status .color = C_SUCCESS if n else C_WARN
1144+ if n :
1145+ refresh_status .value = f"✓ { n } course{ 's' if n != 1 else '' } loaded."
1146+ refresh_status .color = C_SUCCESS
1147+ elif err :
1148+ refresh_status .value = f"✗ { err } "
1149+ refresh_status .color = C_ERROR
1150+ else :
1151+ refresh_status .value = "No courses found after filtering."
1152+ refresh_status .color = C_WARN
11471153 page .update ()
11481154 # Rebuild pages AFTER updating status (rebuild replaces the settings page)
11491155 if on_courses_changed :
@@ -1460,7 +1466,7 @@ def _navigate(idx: int) -> None:
14601466
14611467 def _rebuild () -> None :
14621468 """Reload courses from Canvas and rebuild all course-dependent pages."""
1463- _load_courses_from_canvas ()
1469+ _load_courses_from_canvas () # return value intentionally ignored here
14641470 new = _build_pages ()
14651471 pages .clear ()
14661472 pages .extend (new )
0 commit comments