Skip to content

fix: handle StorageFull and I/O errors in Java world save instead of panicking - #787

Merged
louis-e merged 4 commits into
mainfrom
fix/storage-full-error-handling
Mar 14, 2026
Merged

louis-e merged 4 commits into
mainfrom
fix/storage-full-error-handling

Conversation

@louis-e

@louis-e louis-e commented Mar 14, 2026

Copy link
Copy Markdown
Owner

Replace all .expect()/.unwrap() calls in create_region, save_single_region, and save_java with proper error propagation. A Mutex captures the first error from the rayon parallel iterator; save() detects disk-full conditions and calls emit_gui_error() with a clear user-facing message instead of crashing.

louis-e added 2 commits March 14, 2026 19:10
…panicking

Replace all .expect()/.unwrap() calls in create_region, save_single_region,
and save_java with proper error propagation. A Mutex captures the first error
from the rayon parallel iterator; save() detects disk-full conditions and
calls emit_gui_error() with a clear user-facing message instead of crashing.
Copilot AI review requested due to automatic review settings March 14, 2026 18:13
@github-actions

Copy link
Copy Markdown

⏱️ Benchmark run finished in 0m 26s
🧠 Peak memory usage: 1099 MB

📈 Compared against baseline: 30s
🧮 Delta: -4s
🔢 Commit: d08ef3d

🟢 Generation time is unchanged.

📅 Last benchmark: 2026-03-14 18:16:40 UTC

You can retrigger the benchmark by commenting retrigger-benchmark.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves robustness of Java world saving by replacing panic-based error handling with error propagation and user-facing messaging (especially for disk-full scenarios) during the final save step.

Changes:

  • Convert save_java, save_single_region, and create_region to return Result and propagate I/O/serialization errors instead of unwrap/expect.
  • Capture the first error during rayon parallel region saving and return it after the parallel loop completes.
  • In WorldEditor::save(), detect disk-full situations and emit a GUI error/log message rather than crashing.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
src/world_editor/mod.rs Handles save_java() errors and emits a clearer user/GUI message for disk-full vs generic save failures.
src/world_editor/java.rs Propagates errors from region creation and chunk writes; aggregates the first fatal error from parallel region saving.
src/urban_ground.rs Reformats a geo import for readability (no logic changes).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/world_editor/java.rs
Comment thread src/world_editor/java.rs
Comment thread src/world_editor/java.rs
Comment thread src/world_editor/java.rs Outdated
Comment thread src/world_editor/mod.rs Outdated
… create_base_chunk Result, correct disk-full detection

- Replace lock().unwrap() with lock().unwrap_or_else(|p| p.into_inner()) on
  all three Mutex accesses so a poisoned mutex never causes a secondary panic
- Add AtomicBool should_stop for lock-free fast-path early exit in the rayon
  loop; the Mutex is now only acquired when actually storing the error value
- Change create_base_chunk to return Result and propagate the fastnbt
  serialization error with ? instead of unwrap, closing the last panic hole
- Replace inline string-based disk-full detection with is_disk_full_error()
  helper that walks the full error chain via .source(); fixes the 'code: 112'
  pattern which never matched Windows io::Error Display ('os error 112')

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves robustness of Java world saving by replacing panic-on-failure paths with error propagation and user-facing error reporting (notably for disk-full / I/O failures) during the final “save world” stage.

Changes:

  • Added disk-full detection helper and GUI/telemetry error reporting when Java saving fails.
  • Refactored Java Anvil saving helpers (create_region, save_single_region, save_java) to return Result and capture the first error from parallel region writes.
  • Reformatted a long geo import list for readability.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
src/world_editor/mod.rs Adds disk-full detection helper and handles save_java() failures without panicking, including GUI error emission.
src/world_editor/java.rs Converts Java save pipeline to propagate errors instead of unwrap/expect, capturing first failure across rayon workers.
src/urban_ground.rs Splits long geo import across multiple lines.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/world_editor/java.rs
Comment thread src/world_editor/mod.rs Outdated
Comment thread src/world_editor/mod.rs
Comment thread src/world_editor/java.rs
…isk_full_error correctness

Comment 2 (is_disk_full_error docstring/implementation mismatch):
- Walk source chain via .source() which yields &(dyn Error + 'static),
  enabling downcast_ref::<io::Error>() for structured checks
- Check io_err.kind() == ErrorKind::StorageFull and raw_os_error() 112/28
  as primary detection; keep Display string matching as fallback for
  wrappers (e.g. fastanvil) that don't expose io::Error in source chain
- Fix docstring to accurately describe the hybrid approach

Comment 3 (HIGH - genuine regression: save() swallowed errors silently):
- Change save() from void to Result<(), Box<dyn Error + Send + Sync>>
- Return Err(e) after emitting the GUI error, so callers see the failure
- In data_processing.rs, propagate with if let Err(e) = editor.save() { return Err(...) }
- Previously: disk-full showed GUI error but pipeline continued to
  'Finalizing world...' and returned Ok(output_path) - frontend saw success
  Now: pipeline aborts cleanly on save failure

Skipped comment 1 (path context nit - no anyhow dependency, boilerplate cost
outweighs benefit for user-facing errors that already include OS message)
Skipped comment 4 (try_for_each style nit - AtomicBool approach is correct
and has a marginally better fast-path than try_for_each)
@louis-e
louis-e merged commit ed9c3aa into main Mar 14, 2026
2 checks passed
@louis-e
louis-e deleted the fix/storage-full-error-handling branch March 14, 2026 21:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants