Headless SVG Export Macroquad Panic Clarification
Clarified and improved error reporting when drawing routines invoke
Macroquad window or rendering functions (such as `screen_width()` or
`screen_height()`) during headless SVG export (`--export-svg`).
[export.rs](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/src/export.rs)
- Added `ExportError::Execution(String)` variant to represent drawing
execution failures and panics.
- Implemented `std::fmt::Display` and `std::error::Error` for
`ExportError`.
- Created `PanicHookGuard` RAII struct ensuring any installed panic
hooks are automatically restored after execution.
- In `run_headless_svg_export`:
- Chains onto the existing panic hook to preserve standard panic
backtrace and line number information.
- Detects if the panic originated from uninitialized Macroquad context
(`THREAD_ID.is_some()`).
- Emits a clear, prominent diagnostic banner explaining that
window/GUI functions are unavailable in headless mode.
- Catches the panic via `std::panic::catch_unwind` and returns
`Err(ExportError::Execution(...))`.
- In `handle_svg_export`, uses `{e}` (Display) rather than `{e:?}`
(Debug) for cleaner error reporting.
[lib.rs](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib-macros/src/lib.rs)
- Updated the expanded `main` function generated by `#[turtle_main]` to
format errors with `{}` (Display) instead of `{:?}` (Debug).
[sierpinski_triangle.rs](file:///home/dietrich/Projekte/Source/turtlers/turtle-lib/examples/sierpinski_triangle.rs)
- Added documentation notes to the module header and
`sierpinski_triangle_auto` noting that the example requires an active
graphics window and cannot be exported to SVG headlessly because it
queries window dimensions.
---
Executed:
```bash
RUST_BACKTRACE=1 cargo run --example sierpinski_triangle --features svg
-- --export-svg sier.svg
```
Output:
```
thread 'main' (49702) panicked at
/home/dietrich/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/macroquad-0.4.16/src/lib.rs:172:13:
assertion failed: THREAD_ID.is_some()
stack backtrace:
0: __rustc::rust_begin_unwind
...
5: macroquad::window::screen_width
6: sierpinski_triangle::sierpinski_triangle_auto
at ./turtle-lib/examples/sierpinski_triangle.rs:100:20
7: sierpinski_triangle::draw_sierpinski
at ./turtle-lib/examples/sierpinski_triangle.rs:39:5
...
================================================================================
Headless SVG Export Note:
A Macroquad window/rendering function (e.g. `screen_width()`,
`screen_height()`,
or input check) was called while running in headless export mode.
Headless export does not initialize a graphics window. To resolve this:
- Use relative turtle commands or fixed coordinates instead of window
queries, or
- Run the program in windowed GUI mode without the `--export-svg`
flag.
================================================================================
Error exporting SVG: execution error: Drawing function called Macroquad
window/GUI functions (e.g. `screen_width()`, `screen_height()`) which
are unavailable in headless SVG export mode.
```
- Process exited cleanly with exit code 1.
Executed:
```bash
cargo run --example koch --features svg -- --export-svg /tmp/koch.svg
```
Output:
```
SVG exported successfully to: /tmp/koch.svg
```
Exit code 0.
```bash
cargo test --package turtle-lib
cargo clippy --package turtle-lib --features svg -- -Wclippy::pedantic
-Aclippy::cast_precision_loss -Aclippy::cast_sign_loss
-Aclippy::cast_possible_truncation
```
- 17 unit tests + 34 doctests passed (1 ignored doctest).
- Clippy completed with zero warnings.
This commit is contained in:
@@ -17,6 +17,10 @@
|
||||
//! That is relatively easy to implement, as long as you follow these steps and let recursion do
|
||||
//! the rest. Another little bonus this example provides is the ability to customize the drawing
|
||||
//! size: the triangle will stay correctly sized and positioned automatically.
|
||||
//!
|
||||
//! Note: This example queries `screen_width()` and `screen_height()` to calculate positioning
|
||||
//! relative to the window. Consequently, it requires an active graphics window and does not
|
||||
//! support headless SVG export (`--export-svg`).
|
||||
|
||||
use macroquad::window::{screen_height, screen_width};
|
||||
use turtle_lib::*;
|
||||
@@ -86,6 +90,9 @@ fn sierpinski_triangle(turtle: &mut TurtlePlan, level: u8, size: f32) {
|
||||
/// `level` is still required, it can't be computed automatically. However, given the used
|
||||
/// canvas size, it will compute the appropriate size and start point so the triangle gets
|
||||
/// centered and occupies as much drawing space as possible while staying in bounds.
|
||||
///
|
||||
/// Note: Because this function queries window dimensions, it requires an active graphics
|
||||
/// window and cannot be run in headless SVG export mode.
|
||||
fn sierpinski_triangle_auto(turtle: &mut TurtlePlan, level: u8) {
|
||||
let size = TRIANGLE_SIZE;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user