Files
Justin Poehnelt 6f92e5b5f6 fix: stderr/output hygiene rollup (#525)
* fix: stderr/output hygiene rollup — diagnostics to stderr, colored labels, auth propagation

Component 1 (PR #485): Route triage 'no messages' and modelarmor error
bodies to stderr so stdout stays machine-readable.

Component 2 (PR #466): Add colored error[variant]: labels to stderr
on TTY, respecting NO_COLOR. Replace emoji hint with colorized text.

Component 3 (PR #446): Propagate auth errors as GwsError::Auth in
calendar, chat, docs, drive, script, sheets helpers instead of
silently proceeding unauthenticated. dry-run bypass preserved.

* fix: deduplicate accessNotConfigured stderr output

Use if/else so that accessNotConfigured errors get the specialized
hint guidance instead of redundantly printing both the generic summary
and the hint. Non-accessNotConfigured Api errors and all other variants
still get the generic error[variant]: summary line.

* test: remove misleading model_armor_post error format test

model_armor_post function. A proper integration test would require
HTTP mocking (e.g. mockito/wiremock) which is out of scope for this PR.

* refactor: deduplicate error printing else branches

Use early return in accessNotConfigured branch so the generic
eprintln! only appears once, eliminating the duplicated else blocks.

* security: sanitize error messages before printing to stderr

Add sanitize_for_terminal() to strip control characters (ANSI escape
sequences, bell, backspace, etc.) from error messages before printing
to stderr, preventing terminal escape injection from API responses.
Newlines and tabs are preserved for readability.

The function is pub(crate) so it can be reused by other modules that
print untrusted content to stderr.

* fix: sanitize all stderr error output across codebase

Apply sanitize_for_terminal() to all 16 remaining eprintln sites
that print unsanitized error strings to stderr. This prevents
terminal escape sequence injection through error messages.

Files updated:
- workflows.rs (4 sites)
- watch.rs (2 sites)
- gmail/mod.rs (3 sites)
- executor.rs (1 site)
- subscribe.rs (1 site)
- token_storage.rs (2 sites)
- credential_store.rs (2 sites)
- setup.rs (1 site)
- generate_skills.rs (1 site)

Also fixes clippy: map_err -> inspect_err where closure only logs.

---------

Co-authored-by: jpoehnelt-bot <jpoehnelt-bot@users.noreply.github.com>
2026-03-17 14:15:11 -06:00
..
2026-03-05 23:36:21 +00:00