feat(submissions): diagnostic logging across the translation-enqueue phases#206
Conversation
…phases
Today's investigation into post 1508 (Eucharistic Miracles) cost a lot
of time because cdcf_enqueue_translations_for_submission ran with
almost no observability — the function only logged on explicit failure
paths (Polylang inactive, source missing, individual wp_insert_post
failure, atomic save returning false). All the SILENT happy paths and
the "all langs already linked" no-op path were invisible to
production log greps.
For 1508 the actual sequence was:
ENTER post_id=1508 pre_seed={en:1508}
PHASE_1_DONE newly_created={it:1511, es:1512, fr:1513, pt:1514, de:1515}
PHASE_2_OK final_group={en:1508, it:1511, ...}
PHASE_3_DONE queued 5 jobs via redis
None of which we could see in the FPM logs — only the worker's
"Translation complete for post N (lang)" lines from cdcf_process_translation.
We had to grep the access log and reconstruct timing from worker
completion timestamps to figure out the hook had actually succeeded
and the Polylang group disconnected SOMEHOW between hook completion
(03:00:28) and the next hook fire (03:21:00).
This adds 5 structured error_log lines at each phase transition with
a uniform shape:
ENTER post_id=X post_type=Y pre_seed_group={...}
PHASE_1_DONE post_id=X newly_created={...} already_linked={...}
PHASE_2_OK post_id=X atomic group save succeeded; final_group={...}
(or already-existing PHASE_2_FAIL on save returning false)
PHASE_3_DONE post_id=X queued N job(s) via redis|wp-cron: {...}
NO_OP post_id=X (all target langs already pre-seeded)
Each line is a single grep -E 'PHASE_|ENTER|NO_OP' away from a
complete timeline. Volume: ~3-5 lines per submission publish (one
publish per public referral approval, so a few per week max). Per-
sibling worker logs (1 per translation) are unchanged.
New helper cdcf_format_lang_map() centralizes the {lang:id} formatting
so the lines are consistent and parseable. 4 unit tests for it: empty
array, single entry, 6-language order preservation, string->int
coercion.
553/553 theme suite green. No production behavior change — purely
additional logging.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughUpdated the translation enqueue function with structured diagnostic logging at entry, phase completion, and failure checkpoints. Introduced a new helper function to format language-to-post-id maps compactly for log output, with comprehensive test coverage for empty, single, and multi-language scenarios. ChangesDiagnostic Logging
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 4 |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
Summary
Adds structured per-phase
error_loglines tocdcf_enqueue_translations_for_submissionso future incidents are diagnosable from production FPM logs alone.Today's investigation into post 1508 (Eucharistic Miracles — "auto-translation didn't happen") consumed a lot of time because the function only logged on explicit failure paths:
Polylang not activeSource post N not foundFailed to create {lang} siblingpll_save_post_translations returned false; rolling back N draft(s)All the silent happy paths and the "all langs already linked" no-op path were invisible. We could only reconstruct what happened from the worker's
cdcf_process_translation: Translation complete for post N (lang)lines + access-log timestamps. The actual story turned out to be: the hook DID create translation siblings successfully, but the Polylang group connection got disconnected somehow after the worker finished. Without entry/exit logs in the hook, we couldn't even confirm it had fired correctly until digging through 5 layers of secondary evidence.What the new logs look like
Uniform shape, parseable, one line per phase transition:
Or for the no-op path (all langs already pre-seeded from a partial re-run):
The existing
PHASE_2_FAILrollback log is preserved with the same shape —post_id=X pll_save_post_translations returned false; rolling back N draft(s): {it:X, es:Y, ...}.A single
grep -E 'PHASE_|ENTER|NO_OP'against the FPM log now produces a complete timeline per submission publish.Volume
cdcf_process_translation: Translation complete for post N (lang)) are unchangedImplementation
cdcf_format_lang_map(array): stringcentralizes the{lang:id, lang:id, ...}formatting so all lines parse consistently. Empty array →"{}". String-numeric IDs (which ACF / Polylang sometimes return) are coerced to int.Test plan
php -lcleancomposer test --working-dir=wordpress/themes/cdcf-headless— 553/553 pass (+4 new helper tests; existing 549 unchanged)cdcf_enqueue_translations_for_submission:lines in the FPM log (where today's runs produced 0 on the happy path)Deploy
Backend (theme) change — ship via
gh workflow run deploy.yml -f environment=productionafter merge.Related
/link-term-translationscompanion endpoint (still in review)Follow-ups (out of scope here)
cdcf_link_referral_on_publish(PR feat(submissions): auto-link approved referrals to parent page on publish #200) andcdcf_propagate_project_tags_on_publish(PR feat(submissions): propagate project_tag terms to translated siblings on publish #201) would close the next investigation gap — they have the same silent-happy-path shape🤖 Generated with Claude Code
Summary by CodeRabbit
Tests
Chores