Skip to content

refactor: remove defensive/fallback code patterns (F09/F10/F11/F26/F27)#30

Merged
rsecss merged 1 commit into
mainfrom
refactor/remove-defensive-code
May 23, 2026
Merged

refactor: remove defensive/fallback code patterns (F09/F10/F11/F26/F27)#30
rsecss merged 1 commit into
mainfrom
refactor/remove-defensive-code

Conversation

@rsecss

@rsecss rsecss commented May 23, 2026

Copy link
Copy Markdown
Owner

Summary

Closes F09/F10/F11/F26/F27 from docs/.local/v1.0.0-audit-report.md §2.1 — the user's most-loathed defensive/fallback patterns. Establishes the invariant-at-boundary + log-don't-swallow baseline going into v0.7.0. Epic sub-branch #3 of 9.

Rules now codified

  • Internal invariant violations → expect / unreachable!, never unwrap_or
  • Boundary failures → explicit error propagation or log + handle, never let _ =
  • No // future phases / // best-effort / // may hold state comments

F-id resolution

F-id Where What
F09 services/window.rs Removed 2 let _ = &self; + future-phases comment. Deleted unreachable create_fallback_window. Renamed create_degraded_windowcreate_maximized_window with Why-comment for real Linux compositor / Windows monitor-disconnect recovery.
F10 services/tray.rs show_main_window no longer silently swallows emit/unminimize via let _ =. Each step warns explicitly.
F11 pages/main/SettingsPage.svelte catch (_) { /* best-effort */ } → named error path with [role=alert] banner. zh-CN/en i18n keys added.
F26 timer/state.rs + commands/mod.rs Invariant work_duration > pre_alert_duration moved to config boundary (validate_timer_config). Internal .expect() with documented invariant.
F27 services/stat.rs PR #27 already transactionalized v1→v2. Found and fixed remaining v0→v1 inconsistency: extracted to migrate_initial_to_v1 inside a single transaction with plain CREATE TABLE. v1→v2 keeps IF NOT EXISTS because user-restored-snapshot scenario is real and tested.

Bonus cleanup: silent let _ = in lib.rs (window.hide) and platform/windows.rs (CloseHandle) replaced with logged paths. 4 remaining let _ = cases each annotated with Why-comments (OnceCell race winner, watch::Sender no-receivers, Drop try_send/join_handle non-propagation).

Grep verification

Pattern Before After
catch (_) in src/ 1 0
// future phases / may hold state in future 2 0
unwrap_or numeric-fallback at timer/state.rs 1 0
let _ = in src-tauri/src/ 10 4 (all annotated)

Tests

  • 3 new Rust config invariant tests: timer_config_accepts_defaults, timer_config_rejects_work_le_pre_alert, timer_config_accepts_work_just_above_pre_alert
  • 1 new Svelte test: "surfaces error banner when both save and revert fail"
  • 191 Rust passed (default + --no-default-features), 98 Svelte passed
  • Coverage: 89% lines / 86.49% branches / 86.44% functions (above 80/70 gate from ci(coverage): add 80/70 frontend + 80% backend coverage gate #26)
  • Local npm run ci 8/8 steps pass

Constraints honored

Audit context

Part of v0.7.0 hardening epic — see .trellis/tasks/05-23-v0-7-0-hardening-release-epic/prd.md. Concurrent: #5 macOS fullscreen degrade (PR #29).

🤖 Generated with Claude Code

Removes the most-hated defensive code patterns from the v1.0.0 audit
(docs/.local/v1.0.0-audit-report.md §2.1). Establishes the invariant-at-
boundary + log-don't-swallow baseline going into v0.7.0.

Rules now codified by behavior:
- Internal invariant violations → expect/unreachable, never unwrap_or
- Boundary failures → explicit error propagation or log+handle, never let _ =
- No "future phases" / "best-effort" / "may hold state" comments

F09 (window.rs) — removed 2 `let _ = &self;` placeholders + future-phases
comment; deleted unreachable `create_fallback_window` (empty-monitors
fallback on desktop is dead code); renamed `create_degraded_window` to
`create_maximized_window` with Why-comment for the real Linux compositor /
Windows monitor-disconnect recovery case.

F10 (tray.rs) — `show_main_window` no longer silently swallows emit /
unminimize failures via `let _ = ...`; each step now warns explicitly so
a failed tray-menu navigation is observable.

F11 (SettingsPage.svelte) — replaced `catch (_) { /* best-effort */ }`
on autostart rollback with a named error path that surfaces via a
[role=alert] banner. Adds zh-CN/en i18n keys for the failure copy.

F26 (timer/state.rs + commands/mod.rs) — moved the work>pre_alert
invariant to the config boundary (`validate_timer_config` rejects
`work*60 <= pre_alert`). Internal subtraction sites use `.expect()` with
the invariant documented; numeric underflow fallback removed.

F27 (stat.rs) — PR #27 already transactionalized v1→v2 migration with
idempotent backfill. Found and fixed remaining inconsistency: v0→v1
path used 4 separate `pool.execute` calls with `CREATE TABLE IF NOT
EXISTS`. Extracted to `migrate_initial_to_v1` running inside a single
transaction with plain `CREATE TABLE`. v1→v2 keeps `IF NOT EXISTS`
because the user-restored-snapshot scenario is real and tested.

Also: replaced silent `let _ =` in lib.rs (window.hide) and
platform/windows.rs (CloseHandle) with logged failure paths. The 4
remaining `let _ =` cases each have inline Why-comments justifying
that dropping the result is the correct semantic (OnceCell race winner,
watch::Sender no-receivers, Drop try_send/join_handle that cannot
propagate).

Tests: 3 new Rust config invariant tests + 1 Svelte error-banner test.
Total: 191 Rust passed (default + --no-default-features), 98 Svelte
passed, coverage 89% lines / 86.49% branches / 86.44% functions (above
80/70 gate from #26).

Grep verification:
- `catch (_)` in src/: 0 (was 1)
- `// future phases` / `may hold state in future`: 0 (was 2)
- `unwrap_or` numeric-fallback at timer state.rs: 0 (was 1)
- `let _ =` in src-tauri/src/: 4 (was 10), each annotated

Refs: docs/.local/v1.0.0-audit-report.md F09/F10/F11/F26/F27
Epic: v0.7.0 hardening (sub-branch #3 of 9)
@rsecss rsecss force-pushed the refactor/remove-defensive-code branch from bad6891 to e776a2f Compare May 23, 2026 12:58
@rsecss rsecss merged commit e97b055 into main May 23, 2026
6 checks passed
@rsecss rsecss deleted the refactor/remove-defensive-code branch May 23, 2026 13:04
@rsecss rsecss mentioned this pull request May 23, 2026
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant