feat(errors): structured Q-5-6/Q-5-7 diagnostics for resource-copy failures (bd-bxrkxblx)#318
Merged
Merged
Conversation
…ilures (bd-bxrkxblx)
Referencing a resource (e.g. an image) whose source was missing produced a
plain, code-less `error: <doc>: failed to copy <src> -> <dest>: No such file
or directory (os error 2)` from `OutputSinkError::Copy`, flattened to
`QuartoError::other(String)` and printed via the legacy single-line path. No
error code, no explanation, no source span.
Split the two failure modes and give each a catalog code + docs page:
- Q-5-6 "Referenced resource not found" — a *warning*, located at the
offending reference. Detected at the drain site via `runtime.is_file(src)`
*before* the copy is attempted; the render continues without the file
(matching Quarto 1's tolerant behavior). Underlines the exact ``.
- Q-5-7 "Resource copy failed" — a hard *error* for a genuine flush-time copy
fault (permission denied, disk full). Span-less; the underlying
`io::ErrorKind` is surfaced as advisory detail. Routes through the pretty
reporting path via `QuartoError::Parse`.
Implementation:
- `ResourceCopyIntent { src, dest, origin: SourceInfo }` replaces the bare
`(PathBuf, PathBuf)` copy-intent tuple, carrying the reference's span
(`img.target_source.url`, falling back to `img.source_info`). Threaded
through the render context, stage context, collector, and both drain sites.
- New `resource_copy_diagnostics` module with the two converters plus shared
`enqueue_resource_copies` (existence-check + enqueue) and `copy_failure_error`
helpers, mirroring `resource_error_to_parse_error`. Both native
(`render_document_to_file`) and WASM/preview
(`pass2_renderer::flush_resource_copies`) drains use them. Only
`OutputSinkError::Copy` routes to Q-5-7; HTML-write / dir-create faults keep
their existing path.
Tests:
- Catalog presence test for Q-5-6/Q-5-7.
- Converter unit tests (missing→Q-5-6 located warning; permission-denied→Q-5-7
with advisory; disk-full surfaces the raw OS message).
- Integration regression tests (single-doc + website) asserting the missing
image yields a Q-5-6 warning and the render still succeeds.
Docs: `docs/errors/project/Q-5-6.qmd`, `Q-5-7.qmd`.
Verified end-to-end: `q2 render` of a doc with a missing image prints the
pretty [Q-5-6] diagnostic underlining the reference, exit 0, HTML produced;
`q2 render docs/` turns the former hard copy error into Q-5-6 warnings
(166/166 files rendered). Full `cargo nextest run --workspace` and
`cargo xtask verify` green.
Plan: claude-notes/plans/2026-06-19-resource-copy-error-diagnostic.md
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Summary
Referencing a resource (e.g. an image) whose source is missing previously produced a plain, code-less error from
OutputSinkError::Copy, flattened toQuartoError::other(String)and printed via the legacy single-line path:No error code, no explanation, no source span. This PR routes it (and its sibling I/O faults) through
quarto-error-reportingas structured diagnostics, splitting the two failure modes:Q-5-6"Referenced resource not found" — a warning, located on the offendingreference. Detected viaruntime.is_file(src)before the copy is attempted; the render continues without the file (matching Quarto 1's tolerant behavior).Q-5-7"Resource copy failed" — a hard error for a genuine flush-time fault (permission denied, disk full). Span-less; the underlyingio::ErrorKindis surfaced as advisory detail. Reaches the pretty reporting path viaQuartoError::Parse.Implementation
ResourceCopyIntent { src, dest, origin: SourceInfo }replaces the bare(PathBuf, PathBuf)copy-intent tuple, carrying the reference's span (img.target_source.url, falling back toimg.source_info). Threaded through the render context, stage context, collector, and both drain sites.resource_copy_diagnosticsmodule with the two converters plus sharedenqueue_resource_copies(existence-check + enqueue) andcopy_failure_errorhelpers, mirroring the existingresource_error_to_parse_errorprecedent. Both the native (render_document_to_file) and WASM/preview (pass2_renderer::flush_resource_copies) drains use them.OutputSinkError::Copyroutes toQ-5-7; HTML-write / dir-create faults keep their existing path.Tests
Q-5-6/Q-5-7.Q-5-6located warning; permission-denied →Q-5-7with advisory; disk-full surfaces the raw OS message.Q-5-6warning and the render still succeeds.Docs
docs/errors/project/Q-5-6.qmd,docs/errors/project/Q-5-7.qmd.Verification
cargo nextest run --workspace— 10,284 passed.cargo xtask verify(Rust + WASM + hub-client builds and tests) — all steps passed.q2 renderof a doc with a missing image prints the pretty[Q-5-6]diagnostic underlining the reference, exit 0, HTML produced.q2 render docs/turns the former hard copy error intoQ-5-6warnings (168/168 files rendered).The one remaining
errorin a fulldocs/render (duplicate crossref identifier fig-charts) is a pre-existing, unrelated docs-content bug, tracked separately in bd-rr6qzcvu.Plan:
claude-notes/plans/2026-06-19-resource-copy-error-diagnostic.md🤖 Generated with Claude Code