fix(wasm): state() and step() return Result so errors throw JS exceptions (CR-6)

Previously both ReplayPlayer::state() and ::step() returned JsValue::NULL for
both the expected "replay exhausted" case and the unexpected "serialisation
failed" case. JavaScript callers could not distinguish the two.

Now both methods return Result<JsValue, JsValue>:
- step() returns Ok(null) when the replay is finished (expected sentinel)
- step() and state() Err(string) when serde_wasm_bindgen fails (throws JS exception)

Same fix applied to SolitaireGame::state().

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
funman300
2026-05-17 20:48:30 -07:00
parent a4dfb0c6db
commit 7fc98f8801
+18 -7
View File
@@ -193,16 +193,24 @@ impl ReplayPlayer {
} }
/// Snapshot the current `GameState` as a JS object (see `StateSnapshot`). /// Snapshot the current `GameState` as a JS object (see `StateSnapshot`).
pub fn state(&self) -> JsValue { ///
serde_wasm_bindgen::to_value(&self.snapshot()).unwrap_or(JsValue::NULL) /// Throws a JS string exception on serialisation failure (should never
/// occur in practice — `StateSnapshot` contains only primitive types).
pub fn state(&self) -> Result<JsValue, JsValue> {
serde_wasm_bindgen::to_value(&self.snapshot())
.map_err(|e| JsValue::from_str(&e.to_string()))
} }
/// Apply the next move; returns the post-step snapshot, or `null` /// Apply the next move; returns the post-step snapshot, or `null`
/// once the move list is exhausted. /// once the move list is exhausted.
pub fn step(&mut self) -> JsValue { ///
/// Returns `null` (not an exception) when the replay is finished.
/// Throws a JS string exception on serialisation failure.
pub fn step(&mut self) -> Result<JsValue, JsValue> {
match self.step_native() { match self.step_native() {
Some(snap) => serde_wasm_bindgen::to_value(&snap).unwrap_or(JsValue::NULL), Some(snap) => serde_wasm_bindgen::to_value(&snap)
None => JsValue::NULL, .map_err(|e| JsValue::from_str(&e.to_string())),
None => Ok(JsValue::NULL),
} }
} }
@@ -364,8 +372,11 @@ impl SolitaireGame {
} }
/// Full pile snapshot as a JS object. /// Full pile snapshot as a JS object.
pub fn state(&self) -> JsValue { ///
serde_wasm_bindgen::to_value(&self.snap()).unwrap_or(JsValue::NULL) /// Throws a JS string exception on serialisation failure.
pub fn state(&self) -> Result<JsValue, JsValue> {
serde_wasm_bindgen::to_value(&self.snap())
.map_err(|e| JsValue::from_str(&e.to_string()))
} }
/// The seed used to deal this game. /// The seed used to deal this game.