FJ-35: fix fj pr status panic on merged PRs (unbound $created_at) #43

Merged
David merged 1 commit from fix/pr-status-merged-panic-FJ-35 into main 2026-06-07 17:25:31 +02:00
Owner

FJ-35: fj pr status panics on merged PRs

Problem

fj pr status <n> panicked on merged PRs with Resolver error: Unknown variable: $created_at, aborting at crates/fj/src/prs.rs in the "Merged by {user} on {date}" path. The msg-pr-status-merged Fluent template referenced $created_at, but the call site bound merged_at, so the date placeholder rendered as DATETIME() and the shared error path panicked. Open PRs were unaffected. This broke unattended CI polling that greps fj pr status output, since the loop only saw panic text once a PR merged.

Fix

  • Rename the template placeholder $created_at to $merged_at in all four locales (en-US, de-DE, zh-Hans, tok), matching the existing merged_at binding (the semantically correct PR field for "Merged by X on Y").
  • Add a non-panicking ftl_try_format! macro plus try_format_pattern, returning Option<String>. The merged-by path now degrades to an unformatted timestamp on any resolver error instead of aborting, so one bad template never kills the command.
  • Add regression tests for the merged, open, and closed-unmerged rendered lines; the merged test asserts the date resolves and no DATETIME( leaks.

Acceptance criteria

  • fj pr status <n> on a merged PR exits 0 and shows "Merged by {user} on {date}" with a resolved date
  • Localization failure in this path degrades to an unformatted timestamp instead of panicking
  • Regression test exercises pr status for open, merged, and closed-unmerged PRs

Verification

cargo fmt --all --check, cargo clippy --all-targets --all-features (clean), and cargo test --workspace (3 new tests pass) all green. Reverting the template to $created_at makes the merged test fail, confirming it guards the bug.

🤖 Generated with Claude Code

## FJ-35: `fj pr status` panics on merged PRs ### Problem `fj pr status <n>` panicked on merged PRs with `Resolver error: Unknown variable: $created_at`, aborting at `crates/fj/src/prs.rs` in the "Merged by {user} on {date}" path. The `msg-pr-status-merged` Fluent template referenced `$created_at`, but the call site bound `merged_at`, so the date placeholder rendered as `DATETIME()` and the shared error path panicked. Open PRs were unaffected. This broke unattended CI polling that greps `fj pr status` output, since the loop only saw panic text once a PR merged. ### Fix - Rename the template placeholder `$created_at` to `$merged_at` in all four locales (en-US, de-DE, zh-Hans, tok), matching the existing `merged_at` binding (the semantically correct PR field for "Merged by X on Y"). - Add a non-panicking `ftl_try_format!` macro plus `try_format_pattern`, returning `Option<String>`. The merged-by path now degrades to an unformatted timestamp on any resolver error instead of aborting, so one bad template never kills the command. - Add regression tests for the merged, open, and closed-unmerged rendered lines; the merged test asserts the date resolves and no `DATETIME(` leaks. ### Acceptance criteria - [x] `fj pr status <n>` on a merged PR exits 0 and shows "Merged by {user} on {date}" with a resolved date - [x] Localization failure in this path degrades to an unformatted timestamp instead of panicking - [x] Regression test exercises pr status for open, merged, and closed-unmerged PRs ### Verification `cargo fmt --all --check`, `cargo clippy --all-targets --all-features` (clean), and `cargo test --workspace` (3 new tests pass) all green. Reverting the template to `$created_at` makes the merged test fail, confirming it guards the bug. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
fix(prs): resolve merge date and stop panic on merged PR status
All checks were successful
Check / fmt + clippy + build + tests (pull_request) Successful in 38s
Create release / Create release from merged PR (pull_request) Has been skipped
ab1227ae9b
`fj pr status <n>` panicked on merged PRs with "Unknown variable: $created_at". The `msg-pr-status-merged` Fluent template referenced `$created_at` while the call site at crates/fj/src/prs.rs bound `merged_at`, so the resolver failed, the date placeholder rendered as `DATETIME()`, and the shared `handle_pattern_errors` path aborted the command. This broke unattended CI polling that greps `fj pr status` output, since the loop only saw panic text after merge.

Rename the template placeholder to `$merged_at` across all four locales (en-US, de-DE, zh-Hans, tok) so the existing `merged_at` binding (the semantically correct PR field for "Merged by X on Y") resolves. Add a non-panicking `ftl_try_format!` / `try_format_pattern` that returns `Option<String>`, and use it in the merged-by path: on any resolver error it degrades to an unformatted timestamp instead of aborting, so one bad template never kills the command.

Add regression tests exercising the rendered lines for merged, open, and closed-unmerged PR states; the merged test asserts the date resolves and no `DATETIME(` leaks.

#FJ-35

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
David merged commit efd5746b15 into main 2026-06-07 17:25:31 +02:00
David deleted branch fix/pr-status-merged-panic-FJ-35 2026-06-07 17:25:31 +02: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
pandoras-box/forgejo-cli!43
No description provided.