Diagnose Withings refresh failures and accept documented token response #4
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/refresh-numeric-userid-and-status-diagnostic"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Source-only fix for Withings refresh and sanitized failure diagnosis. Official authorization responses use numeric userid and include scope; documented refresh responses may omit both. Preserve stored identity/scope on refresh, fail closed on incomplete consent, verify full persisted record before using rotated token, and expose only stage and numeric status in error diagnostics. Remove userid from startup logs. Bump rustls lockfile 0.23.43 → 0.23.45 to clear RUSTSEC-2026-0285.
Offline checks at
905b96acb3: fmt, clippy -D warnings, 88 tests, cargo audit and cargo deny all passed on pinned Rust 1.98.0; independent rerun also passed. Synthetic regression sabotage went red. No production token/measurement read, release, or live OAuth probe. The oldwithings_api_errorproves only an unmapped nonzero Withings envelope status; exact live status is unknown. Clark owns tagged release and live verification after review.persist_before_use logged `%error` and put the store's error text into the InvalidInput a client sees, and load_or_unauthorized did the same on both reads before a refresh. A store's error is free text: it can name a path, or quote the file it failed to parse, which holds the credential. Every store failure on the refresh path now goes through one function and becomes WithingsError::TokenStore { step }, with step one of load, persist, read_back or mismatch. The client sees code token_store_error, class internal, stage refresh and store_step. The log carries the step and a bounded cause (io with its ErrorKind, parse, withings, other). The OAuth callback's adopt failure logs the same bounded cause instead of `%error`. Fail-closed ordering is unchanged: persist and read back before the new access token is returned. a_token_store_failure_names_its_step_and_nothing_private drives the real transport through six breakages (first load, re-read under the gate, save, read-back, and read-back and first load returning an unparsable file) with a store whose errors carry an invented sentinel, an invented path and the rotated token. It asserts none of them reaches the envelope or the captured log, and that measure is never called. Putting `%error` back into the log, or the old load_or_unauthorized message back into the envelope, reds it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>