Repository navigation
Retry Typst Google-font fetches, check HTTP status, keep diagnostic detail in smoke-all (bd-qvl8t3hy) - #820
Merged
Conversation
Plan skeleton with triage verdict (ready to design). Confirms the strand's analysis at HEAD and adds three findings: native fetch_url never checks HTTP status, the fetch closure's String error cannot drive a retry policy, and the font CSS is refetched on every render regardless of cache state. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Uniform 3-attempt retry in typst_google_fonts.rs; native fetch_url gets a 30 s timeout and treats non-2xx as an error for all callers; fixtures stay under the default noErrorsOrWarnings; the harness keeps the full plain-text diagnostic rendering. CSS caching is bd-f48l642w. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…d-qvl8t3hy) The harness turned each render diagnostic into a LogMessage carrying only the title, so a noErrorsOrWarnings failure in CI said "Google font not available to Typst" and nothing about which URL or which error. Render the diagnostic as plain text (title, problem, details, hints; no ANSI, no OSC 8) instead, through one diagnostic_to_message helper shared by the project and single-document paths. printsMessage regexes are unanchored, so existing matchers are unaffected. Multi-line messages are indented under their [LEVEL] prefix in assertion failure output. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…rl (bd-qvl8t3hy) fetch_url was a bare reqwest::blocking::get: no timeout, so a stalled connection could hang a render or a CI run, and no status check, so a 404 or 503 came back as Ok with the HTML error page as the body. The Typst Google-font path then parsed that page as a stylesheet and told the user to check the family's spelling. One shared blocking client now carries a 30 s request timeout (matching quarto-source-fetch), a non-2xx status is an error that names the code and the URL, and failures use RuntimeError::Network rather than NotSupported. The native fetch_url_hardened override enforces its FetchPolicy timeout, which the trait default never did on native. Loopback TcpListener tests cover the 200, 503, and stalled-connection cases without a network. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…3hy) stage_google_font gave up on a family after a single failed request, so one transient network error on a CI runner produced a Q-21-4 and failed the smoke-all noErrorsOrWarnings check for the whole render. Both the CSS request and each file download now go through fetch_with_retry under a RetrySchedule: three attempts, waiting 250 ms and then 1 s between them. The schedule's sleep is injected (the module also compiles for wasm32, and tests run it without waiting); the native caller passes RetrySchedule::blocking(). The Q-21-4 text reports the final error and the attempt count. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…cases (bd-qvl8t3hy) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Contributor
✅ Snyk checks have passed. No issues have been found so far.
💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes bd-qvl8t3hy. Plan:
claude-notes/plans/2026-10-10-typst-google-font-flake.md.Problem
cargo xtask verifyruns smoke-all with network access, and the Typst Google-font fixtures occasionally failed with Q-21-4 ("Failed to download Google font") on a transient fetch error. Two things made this worse than a flake:fetch_urlnever checked the HTTP status, so a 503 fromfonts.googleapis.comcame back as a successful fetch of an HTML error page, and it had no request timeout at all.DiagnosticMessageto its title, so the failure log never said which URL or which error was involved.Changes
quarto-core/typst_google_fonts.rs— the CSS request and each font-file download go through a three-attempt schedule (250 ms, then 1 s). The sleep is injected viaRetrySchedule, so unit tests run without waiting and the wasm32 build never references a blocking sleep. Q-21-4 now reports the final error and the attempt count.quarto-system-runtime/native.rs— one sharedreqwest::blocking::Clientwith a 30 s request timeout. A non-2xx status is nowRuntimeError::Network("HTTP <status> for <url>"); transport failures use theNetworkvariant too. The nativefetch_url_hardenedoverride enforces its policy timeout, which the trait default never did. Loopback tests cover a 200, a 503, and a stalled connection.quarto-test— render diagnostics become harness log messages carrying the full plain-text rendering (title, problem, hints) via one shared helper for both render paths. Multi-line messages are indented under their level prefix in assertion failures.printsMessageregexes are unanchored, so existing fixtures are unaffected.quarto-error-catalog— the Q-21-4 entry describes the retry, timeout, and error-status cases.Behavior change for Lua filters
pandoc.mediabag.fetch(and anything else going throughfetch_url) on a URL that answers 404 or 503 now returnsnilwith a stderr line, instead of handing the HTML error page back as content. This is intentional (design decision 2 in the plan).Verification
cargo xtask verify --skip-hub-buildgreen at 8f25d13 (14 steps, 16102 tests, including smoke_all with network).npm run build:wasmgreen, no new warnings.noErrorsOrWarningsassertion.Follow-up
bd-f48l642w tracks caching the Google Fonts CSS response so it is not refetched on every render.
🤖 Generated with Claude Code