mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
A valid link (e.g. a GitHub PR page) could render no preview card for five minutes after a single unlucky fetch, then quietly work again. One slow handshake, a rate-limit blip, or a 5xx would poison the card. Two paths funneled a transient failure into the same sticky negative cache as a genuine "no metadata" miss: - The resolver's fetch loader caught any rejection (timeout, network error) as a plain null and cached it under NULL_METADATA_RETRY_MS (5 minutes). - The native fetcher returned Ok(None) for a retryable page status (429, 408, 425, 5xx), which the resolver also cached for the full miss TTL. Distinguish transient failures from hard misses: - The loader now records a rejected fetch as transient and caches it for the short transient TTL (30s) instead of the 5-minute miss TTL. A resolved null (200 + HTML + no metadata) still holds the full miss TTL. - The native fetcher surfaces a retryable page status as an error (via a shared is_transient_status helper, reused by the image path) so it takes the short transient TTL rather than the sticky negative cache. Also widen the per-request timeout from 4s to 6s (total 10s to 15s) so slow networks stop tripping the transient path in the first place. Tests: JS regression that a rejected fetch clears well before the 5-minute miss TTL while a genuine null miss stays cached; the rejected-retry test now asserts the 30s transient boundary; Rust unit test that retryable statuses are transient and permanent ones (404/403/401/410) are hard misses. Full desktop unit suite 4580 passed; link_preview Rust suite 22 passed. Co-authored-by: Taylor Ho <taylorkmho@gmail.com> Signed-off-by: Taylor Ho <taylorkmho@gmail.com>