#1609: a grouped panic keeps its payload and lets later live edits sync

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: GPT-6.1 Sol <noreply@openai.com>
This commit is contained in:
Mert Dede
2026-10-30 07:13:03 +03:00
co-authored by Claude Opus 5.5 GPT-6.1 Sol
parent 3a59a70b10
commit cc0976a4a2
+40 -1
View File
@@ -40,7 +40,8 @@ fn a_grouped_closure_that_panics_leaves_the_session_as_before() {
})
}));
assert!(unwound.is_err(), "the panic goes on to the caller");
let payload = unwound.unwrap_err();
assert_eq!(payload.downcast_ref::<&str>(), Some(&"a bug in the closure"), "the original panic goes on to the caller");
let ds = s.ds().unwrap();
assert!(Arc::ptr_eq(&ds.doc, &doc));
assert_eq!(*ds.doc, *doc);
@@ -61,6 +62,44 @@ fn a_grouped_closure_that_panics_leaves_the_session_as_before() {
assert_eq!(s.undo_depth(), (depth.0 + 2, 0));
}
#[test]
fn a_grouped_closure_that_panics_releases_the_live_hold_so_later_edits_sync() {
use crate::live_tests::{push, relay, serve, session};
let (mut s, script) = session();
let first = rect(&mut s, 0);
s.execute("collab.host", &json!({})).unwrap();
let (mut server, id, welcome) = serve(s.doc().unwrap());
push(&script, vec![welcome]);
s.live_poll();
assert!(s.live_doc(s.ds().unwrap().uid));
let before = s.doc().unwrap().clone();
script.lock().unwrap().msgs.clear();
let unwound = catch_unwind(AssertUnwindSafe(|| {
s.grouped("Rename then panic", |s| -> crate::Result<()> {
s.execute("node.set", &json!({"id": first, "props": {"name": "Rolled back"}}))?;
s.live_sync();
assert!(script.lock().unwrap().msgs.is_empty(), "the edit waits for the group to end");
panic!("a bug in the live closure");
})
}));
assert!(unwound.is_err());
assert_eq!(s.doc().unwrap(), &before);
s.live_sync();
assert!(script.lock().unwrap().msgs.is_empty(), "the rolled-back edit never goes out");
s.execute("node.set", &json!({"id": first, "props": {"name": "Sent afterwards"}})).unwrap();
s.live_sync();
assert_eq!(script.lock().unwrap().msgs.len(), 1, "the later edit goes out");
let replies = relay(&script, &mut server, id);
push(&script, replies);
s.live_poll();
assert_eq!(server.document().node(first).unwrap().name, "Sent afterwards");
assert_eq!(s.doc().unwrap(), server.document());
}
#[test]
fn a_panic_in_an_inner_group_rolls_back_through_the_outer_one() {
let mut s = Session::new();