mirror of
https://github.com/MadsLorentzen/ai-job-search.git
synced 2026-11-02 13:12:50 +00:00
fix(rank): report a tracker that is not UTF-8 instead of a traceback (#639)
* fix(rank): report a tracker that is not UTF-8 instead of a traceback A job_search_tracker.csv saved with a spreadsheet's plain "CSV" type is written in the ANSI code page, so one accented company name raised a UnicodeDecodeError traceback in `rank_state.py candidates` and stopped /rank at Step 1. Exit 1 with a one-line message instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * changelog: place the #639 entry under [Unreleased] Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Mads Lorentzen <madslorentzen_17@hotmail.com>
This commit is contained in:
3 files changed
+29
-5
No files matched your search
@@ -83,6 +83,12 @@ per-file diff commands.
|
|||||||
whole batch, although `apply` already collects per-result problems in `errors`. Each now becomes an
|
whole batch, although `apply` already collects per-result problems in `errors`. Each now becomes an
|
||||||
`errors` row (exit 1) and the valid results in the same file are still written.
|
`errors` row (exit 1) and the valid results in the same file are still written.
|
||||||
|
|
||||||
|
- **`rank_state.py candidates` reports a tracker that is not UTF-8 instead of crashing** (#639, `tools/rank_state.py`,
|
||||||
|
`tests/test_rank_state.py`) - a `job_search_tracker.csv` saved with a spreadsheet's plain "CSV" type is
|
||||||
|
written in the ANSI code page (cp1252 on most Western installs), so one accented company name such as
|
||||||
|
"Ørsted" raised a `UnicodeDecodeError` traceback and stopped `/rank` at Step 1. It now exits 1 with a
|
||||||
|
one-line message naming the file and asking for a CSV UTF-8 save, as `load_state` does for invalid JSON.
|
||||||
|
|
||||||
## [1.7.3] - 2026-10-19
|
## [1.7.3] - 2026-10-19
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@@ -160,6 +160,19 @@ class Candidates(RankStateCase):
|
|||||||
)
|
)
|
||||||
self.assertEqual(out["excluded_by_tracker"], int(excluded))
|
self.assertEqual(out["excluded_by_tracker"], int(excluded))
|
||||||
|
|
||||||
|
def test_tracker_saved_in_a_legacy_code_page_is_reported_not_a_traceback(self):
|
||||||
|
# A spreadsheet's plain "CSV" save on Windows writes cp1252, not UTF-8.
|
||||||
|
self.write_state({"a": entry()})
|
||||||
|
tracker = self.tmp / "tracker.csv"
|
||||||
|
tracker.write_bytes("date,company,role\r\n2026-08-01,Ørsted,SOC Analyst\r\n".encode("cp1252"))
|
||||||
|
proc = subprocess.run(
|
||||||
|
[sys.executable, str(TOOL), "candidates", "--state", str(self.state), "--tracker", str(tracker)],
|
||||||
|
capture_output=True, text=True, encoding="utf-8",
|
||||||
|
)
|
||||||
|
self.assertEqual(proc.returncode, 1)
|
||||||
|
self.assertIn("is not UTF-8 text - re-save it as CSV UTF-8", proc.stderr)
|
||||||
|
self.assertNotIn("Traceback", proc.stderr)
|
||||||
|
|
||||||
def test_focus_filters_on_title_company_and_stored_fit_notes(self):
|
def test_focus_filters_on_title_company_and_stored_fit_notes(self):
|
||||||
self.write_state(
|
self.write_state(
|
||||||
{
|
{
|
||||||
|
|||||||
+10
-5
@@ -149,11 +149,16 @@ def tracker_pairs(path: Path) -> set[tuple[str, str]]:
|
|||||||
import csv
|
import csv
|
||||||
|
|
||||||
pairs = set()
|
pairs = set()
|
||||||
with path.open(encoding="utf-8-sig", newline="") as fh:
|
try:
|
||||||
for row in csv.DictReader(fh):
|
with path.open(encoding="utf-8-sig", newline="") as fh:
|
||||||
company, role = norm(row.get("company")), norm(row.get("role"))
|
for row in csv.DictReader(fh):
|
||||||
if company:
|
company, role = norm(row.get("company")), norm(row.get("role"))
|
||||||
pairs.add((company, role))
|
if company:
|
||||||
|
pairs.add((company, role))
|
||||||
|
except UnicodeDecodeError:
|
||||||
|
# A spreadsheet's plain "CSV" save writes the ANSI code page (cp1252 on
|
||||||
|
# most Western installs), so any accented company name stops decoding.
|
||||||
|
sys.exit(f"{path} is not UTF-8 text - re-save it as CSV UTF-8")
|
||||||
return pairs
|
return pairs
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user