fix(serve): reorder except clauses so the corrupted-graph message is reachable

json.JSONDecodeError subclasses ValueError, so the broader
`except (ValueError, FileNotFoundError)` clause always matched first,
making the intended "graph.json is corrupted (...). Re-run /graphify
to rebuild." recovery hint dead code — users with a truncated graph.json
got the bare json.JSONDecodeError message instead, contradicting the
behavior SECURITY.md documents for this exact threat.

Move the json.JSONDecodeError clause first so it actually catches.
Audited the rest of serve.py's exception handlers for the same
narrower-after-broader ordering bug; found no other instance.

Fixes #2005.
This commit is contained in:
김재현
2026-07-20 15:02:54 +01:00
committed by safishamsi
parent 6bbc9d14c6
commit b890ca6590
2 changed files with 16 additions and 3 deletions
+3 -3
View File
@@ -55,12 +55,12 @@ def _load_graph(graph_path: str) -> nx.Graph:
except Exception:
G.graph["_learning_overlay"] = {}
return G
except (ValueError, FileNotFoundError) as exc:
print(f"error: {exc}", file=sys.stderr)
sys.exit(1)
except json.JSONDecodeError as exc:
print(f"error: graph.json is corrupted ({exc}). Re-run /graphify to rebuild.", file=sys.stderr)
sys.exit(1)
except (ValueError, FileNotFoundError) as exc:
print(f"error: {exc}", file=sys.stderr)
sys.exit(1)
def _communities_from_graph(G: nx.Graph) -> dict[int, list[str]]:
+13
View File
@@ -599,6 +599,19 @@ def test_load_graph_missing_file(tmp_path):
_load_graph(str(graphify_dir / "nonexistent.json"))
def test_load_graph_corrupted_json_prints_recovery_message(tmp_path, capsys):
"""json.JSONDecodeError is a ValueError subclass, so its except clause
must be checked before the bare (ValueError, FileNotFoundError) clause,
or the corrupted-graph recovery hint is unreachable (#2005)."""
p = tmp_path / "graph.json"
p.write_text("{not valid json")
with pytest.raises(SystemExit):
_load_graph(str(p))
err = capsys.readouterr().err
assert "graph.json is corrupted" in err
assert "Re-run /graphify to rebuild" in err
def test_load_graph_rejects_oversized_file(monkeypatch, tmp_path, capsys):
# #F4: oversized graph.json must fail fast (SystemExit) with a clear error.
G = _make_graph()