fix(setup): TETRA-1975 — loại bỏ nuốt exception im lặng (log-then-raise + gate ruff S110) #162

Merged
tant merged 2 commits from fix/TETRA-1975-fail-loud-exceptions into main 2026-06-12 15:44:28 +07:00
Owner

Mục tiêu

Hoàn tất TETRA-1975: sau 31fac77 (verification cuối pipeline), các phase setup/patch critical giờ fail-loud tại chỗbench install-app / bench migrate không còn exit 0 khi setup hỏng một phần.

Thay đổi

Setup hooks — log rồi raise / throw tổng kết cuối loop

File Trước Sau
setup/payroll.py log + return log traceback + re-raise
setup/permissions.py log + return log traceback + re-raise
setup/asset_categories.py per-item log, kết thúc im lặng per-item log + throw tổng kết nếu có failed
setup/translations.py (2 loop rename) log + continue, im lặng guard skip khi tên VI đã tồn tại (duplicate hợp lệ); lỗi thật → throw tổng kết
setup/ensure_accounts.py parent-not-found + insert lỗi chỉ log đều tính failed → throw tổng kết (thiếu VAS account = Salary Slip vỡ)
setup/holiday_list_assignment.py stats[failed] chỉ logger.info throw tổng kết sau loop
setup/holiday_list_migration.py delete fail chỉ log thêm summary["failed"] + throw tổng kết (loop vẫn chạy hết)

Patches — chỉ raise khi patch KHÔNG làm xong việc

  • v0_5_0/migrate_salary_structure_templates.py: ImportError + delete template cũ fail → log + re-raise (patch retry lần migrate sau).
  • v0_5_0/update_pit_formula_5_brackets.py: ImportError → log + re-raise (im lặng = site tính thuế biểu cũ).
  • v0_9_0/rename_d02_ts_to_d02_lt.py: gom lỗi 3 step, throw tổng kết cuối.
  • Đã confirm các patch có sẵn counter+summary (v0_7_0 snapshots, v0_9_0 compa-ratio, v0_10_0 SSA slab): giữ nguyên.
  • Per-record skip hợp lệ (record không áp dụng) vẫn là logged skip — không block migrate.

Bare except-pass (audit ~29 site)

  • 15 site bị ruff S110 flag (bare/Exception): tất cả là guard có chủ đích (tearDown cleanup, autofill best-effort, optional field, stub fall-through) → gắn # noqa: S110 kèm lý do từng dòng. Không đổi hành vi.
  • 14 site typed-exception (AttributeError, ImportError, DuplicateEntryError...) không bị flag với config mặc định (check-typed-exception=false) — typed = đã chủ đích, giữ nguyên.
  • Site giữ nguyên có chủ đích: income_tax_slab.py build-slab skip (retry path + được run_verification cover), leave_types.py meta-guards + delegate.

Lint gate

  • pyproject.toml: thêm per-rule "S110" vào select (không bật cả set S để tránh noise).
  • CI test.yml: step mới ruff check --select S110 . (pin ruff==0.8.1 khớp pre-commit). Lưu ý: full-rule ruff check . còn ~550 lỗi baseline (I001/RUF002/RUF003 — phần lớn ký tự tiếng Việt trong docstring) → follow-up riêng, không gate ở đây.

Test

  • ruff check --select S110 .0 lỗi; không phát sinh violation mới trên file đã sửa (diff so với main).
  • Offline tests chạy từng file (tránh sys.modules stub collision): holiday_list_migration (9), setup_verification (14), compute (18), dynamic_lookups (8), oob_approval_workflow (19), asset_categories (5), t13_bonus, bhxh_claim_export (14), holiday_rest_day_split (12), payroll_deductions (34), ot_night_auto_detect (26), npt_api_transition (32) — tất cả PASS.
  • test_holiday_list_migration cập nhật: summary có key failed; case delete-fail expect throw tổng kết sau khi loop chạy hết.
  • Module không có offline test: setup/payroll, permissions, translations, ensure_accounts, holiday_list_assignment, 3 patch files — verify bằng ruff + py_compile; hành vi raise sẽ lộ ngay ở lần bench migrate staging kế tiếp.

Rủi ro

  • Site đang có lỗi setup ngầm (trước đây bị nuốt) sẽ fail migrate sau PR này — đây là chủ đích của ticket; Error Log có đầy đủ chi tiết từng item trước khi throw.

Refs: TETRA-1975

🤖 Generated with Claude Code

## Mục tiêu Hoàn tất TETRA-1975: sau 31fac77 (verification cuối pipeline), các phase setup/patch critical giờ **fail-loud tại chỗ** — `bench install-app` / `bench migrate` không còn exit 0 khi setup hỏng một phần. ## Thay đổi ### Setup hooks — log rồi raise / throw tổng kết cuối loop | File | Trước | Sau | |---|---|---| | `setup/payroll.py` | log + return | log traceback + **re-raise** | | `setup/permissions.py` | log + return | log traceback + **re-raise** | | `setup/asset_categories.py` | per-item log, kết thúc im lặng | per-item log + **throw tổng kết** nếu có failed | | `setup/translations.py` (2 loop rename) | log + continue, im lặng | guard skip khi tên VI đã tồn tại (duplicate hợp lệ); lỗi thật → **throw tổng kết** | | `setup/ensure_accounts.py` | parent-not-found + insert lỗi chỉ log | đều tính failed → **throw tổng kết** (thiếu VAS account = Salary Slip vỡ) | | `setup/holiday_list_assignment.py` | stats[failed] chỉ logger.info | **throw tổng kết** sau loop | | `setup/holiday_list_migration.py` | delete fail chỉ log | thêm `summary["failed"]` + **throw tổng kết** (loop vẫn chạy hết) | ### Patches — chỉ raise khi patch KHÔNG làm xong việc - `v0_5_0/migrate_salary_structure_templates.py`: ImportError + delete template cũ fail → log + re-raise (patch retry lần migrate sau). - `v0_5_0/update_pit_formula_5_brackets.py`: ImportError → log + re-raise (im lặng = site tính thuế biểu cũ). - `v0_9_0/rename_d02_ts_to_d02_lt.py`: gom lỗi 3 step, throw tổng kết cuối. - Đã confirm các patch có sẵn counter+summary (v0_7_0 snapshots, v0_9_0 compa-ratio, v0_10_0 SSA slab): giữ nguyên. - Per-record skip hợp lệ (record không áp dụng) vẫn là logged skip — không block migrate. ### Bare except-pass (audit ~29 site) - 15 site bị ruff S110 flag (bare/`Exception`): tất cả là guard có chủ đích (tearDown cleanup, autofill best-effort, optional field, stub fall-through) → gắn `# noqa: S110` kèm lý do từng dòng. Không đổi hành vi. - 14 site typed-exception (`AttributeError`, `ImportError`, `DuplicateEntryError`...) không bị flag với config mặc định (`check-typed-exception=false`) — typed = đã chủ đích, giữ nguyên. - Site giữ nguyên có chủ đích: `income_tax_slab.py` build-slab skip (retry path + được `run_verification` cover), `leave_types.py` meta-guards + delegate. ### Lint gate - `pyproject.toml`: thêm per-rule `"S110"` vào select (không bật cả set S để tránh noise). - CI `test.yml`: step mới `ruff check --select S110 .` (pin ruff==0.8.1 khớp pre-commit). Lưu ý: full-rule `ruff check .` còn ~550 lỗi baseline (I001/RUF002/RUF003 — phần lớn ký tự tiếng Việt trong docstring) → follow-up riêng, không gate ở đây. ## Test - `ruff check --select S110 .` → **0 lỗi**; không phát sinh violation mới trên file đã sửa (diff so với main). - Offline tests chạy **từng file** (tránh sys.modules stub collision): holiday_list_migration (9), setup_verification (14), compute (18), dynamic_lookups (8), oob_approval_workflow (19), asset_categories (5), t13_bonus, bhxh_claim_export (14), holiday_rest_day_split (12), payroll_deductions (34), ot_night_auto_detect (26), npt_api_transition (32) — **tất cả PASS**. - `test_holiday_list_migration` cập nhật: summary có key `failed`; case delete-fail expect throw tổng kết sau khi loop chạy hết. - Module không có offline test: setup/payroll, permissions, translations, ensure_accounts, holiday_list_assignment, 3 patch files — verify bằng ruff + py_compile; hành vi raise sẽ lộ ngay ở lần `bench migrate` staging kế tiếp. ## Rủi ro - Site đang có lỗi setup ngầm (trước đây bị nuốt) sẽ **fail migrate** sau PR này — đây là chủ đích của ticket; Error Log có đầy đủ chi tiết từng item trước khi throw. Refs: TETRA-1975 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(setup): TETRA-1975 — loại bỏ nuốt exception im lặng (log-then-raise + gate ruff S110)
Some checks failed
Test (offline) / test (pull_request) Waiting to run
Test (offline) / test (push) Failing after 5m35s
22bc37cb43
Hoàn tất phần còn lại của TETRA-1975 sau 31fac77 (verification cuối pipeline):
các phase setup/patch critical giờ tự fail-loud tại chỗ thay vì chỉ dựa vào
lưới verification.

Setup hooks (log rồi raise / throw tổng kết cuối loop):
- payroll.py: tạo Payroll Period fail → log + re-raise (trước: log + return).
- permissions.py: setup ESS permission fail → log + re-raise.
- asset_categories.py: loop seed giữ per-item log, gom failed → throw tổng kết.
- translations.py: 2 loop rename (Employment Type + Designation) — thêm guard
  skip khi tên tiếng Việt đã tồn tại (duplicate hợp lệ), lỗi thật → gom +
  throw tổng kết thay vì msgprint/log rồi im lặng.
- ensure_accounts.py: parent-not-found và insert lỗi đều tính failed → throw
  tổng kết (thiếu VAS account = Salary Slip submit vỡ). DuplicateEntryError
  race giữ nguyên (end-state đạt).
- holiday_list_assignment.py: stats["failed"] > 0 → throw tổng kết sau loop.
- holiday_list_migration.py: thêm summary["failed"], delete legacy fail →
  throw tổng kết sau khi xử lý hết các list (refs đã redirect vẫn giữ).

Patches (chỉ raise khi patch KHÔNG làm xong việc):
- v0_5_0/migrate_salary_structure_templates.py: ImportError + delete template
  cũ fail → log + re-raise (patch sẽ retry lần migrate sau).
- v0_5_0/update_pit_formula_5_brackets.py: ImportError → log + re-raise
  (im lặng = site tính thuế theo biểu cũ).
- v0_9_0/rename_d02_ts_to_d02_lt.py: gom lỗi 3 step, throw tổng kết cuối.
- v0_7_0/backfill_salary_slip_snapshots, v0_9_0/backfill_compa_ratio_legacy,
  v0_10_0/backfill_ssa_income_tax_slab: đã có counter + summary — giữ nguyên.

Bare except-pass (15 site S110): tất cả là guard có chủ đích (cleanup
tearDown, autofill best-effort, optional field, stub fall-through) — gắn
`# noqa: S110` kèm lý do từng dòng, không đổi hành vi.

Lint gate:
- pyproject.toml: thêm per-rule "S110" vào [tool.ruff.lint] select.
- CI test.yml: thêm step `ruff check --select S110 .` (pin ruff==0.8.1 khớp
  pre-commit). Full-rule check còn ~550 lỗi baseline (I001/RUF002/RUF003 —
  phần lớn ký tự tiếng Việt trong docstring) → dọn ở follow-up riêng.

Test: cập nhật test_holiday_list_migration (summary có key "failed"; case
delete-fail giờ expect throw tổng kết sau khi loop chạy hết). Đã chạy từng
file: test_holiday_list_migration, test_setup_verification, test_compute,
test_dynamic_lookups, test_oob_approval_workflow, test_asset_categories,
test_t13_bonus, test_bhxh_claim_export, test_holiday_rest_day_split,
test_payroll_deductions, test_ot_night_auto_detect, test_npt_api_transition
— tất cả PASS. ruff S110 toàn repo: 0 lỗi.

Refs: TETRA-1975

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
test(hrms): TETRA-1975 — cập nhật test_hla_backfill theo contract fail-loud mới
All checks were successful
Test (offline) / test (push) Successful in 43s
Test (offline) / test (pull_request) Successful in 3m35s
e4b74d753b
Case insert-failure trước đây assert "Must NOT raise" — contract cũ (nuốt lỗi
im lặng) đã bị thay ở holiday_list_assignment.py: loop vẫn chạy hết các
employee còn lại nhưng kết thúc bằng throw tổng kết khi có record fail.
Test giờ expect ValidationError + vẫn assert per-item log và 2 doc sau được
insert/submit đầy đủ. CI run 59 bắt được đúng case này — toàn bộ 70 module
offline đã re-run pass local.

Refs: TETRA-1975

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
tant merged commit cf5ad25bd6 into main 2026-06-12 15:44:28 +07:00
tant deleted branch fix/TETRA-1975-fail-loud-exceptions 2026-06-12 15:44:29 +07:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
tant/vhrms!162
No description provided.