Skip to content

Commit b320864

Browse files
committed
frontend -- fix several cases of uncaught exceptions when object is closed while waiting for "ready" state using once
1 parent d3d8c3e commit b320864

File tree

4 files changed

+47
-11
lines changed

4 files changed

+47
-11
lines changed

src/packages/frontend/frame-editors/code-editor/actions.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1636,8 +1636,15 @@ export class Actions<
16361636
}
16371637

16381638
if (this._syncstring.get_state() != "ready") {
1639-
await once(this._syncstring, "ready");
1640-
if (this.isClosed()) return;
1639+
try {
1640+
await once(this._syncstring, "ready");
1641+
} catch {
1642+
// never made it
1643+
return;
1644+
}
1645+
if (this.isClosed()) {
1646+
return;
1647+
}
16411648
}
16421649

16431650
// NOTE: we fallback to getting the underlying CM doc, in case all actual
@@ -1751,7 +1758,12 @@ export class Actions<
17511758
const state = syncdoc.get_state();
17521759
if (state == "closed") return false;
17531760
if (state == "init") {
1754-
await once(syncdoc, "ready");
1761+
try {
1762+
await once(syncdoc, "ready");
1763+
} catch {
1764+
// never mode it
1765+
return false;
1766+
}
17551767
if (this.isClosed()) return false;
17561768
}
17571769
return true;

src/packages/frontend/frame-editors/latex-editor/actions.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -260,9 +260,16 @@ export class Actions extends BaseActions<LatexEditorState> {
260260

261261
// Wait until the syncstring is loaded from disk.
262262
if (this._syncstring.get_state() == "init") {
263-
await once(this._syncstring, "ready");
263+
try {
264+
await once(this._syncstring, "ready");
265+
} catch {
266+
// closed before finished opening
267+
return;
268+
}
269+
}
270+
if (this._state == "closed") {
271+
return;
264272
}
265-
if (this._state == "closed") return;
266273

267274
let program = ""; // later, might contain the !TeX program build directive
268275
let cocalc_cmd = ""; // later, might contain the cocalc command
@@ -327,9 +334,16 @@ export class Actions extends BaseActions<LatexEditorState> {
327334
this._init_syncdb(["key"], undefined, path);
328335

329336
// Wait for the syncdb to be loaded and ready.
330-
if (this._syncdb == null) throw Error("syncdb must be defined");
337+
if (this._syncdb == null) {
338+
throw Error("syncdb must be defined");
339+
}
331340
if (this._syncdb.get_state() == "init") {
332-
await once(this._syncdb, "ready");
341+
try {
342+
await once(this._syncdb, "ready");
343+
} catch {
344+
// user closed it
345+
return;
346+
}
333347
if (this._state == "closed") return;
334348
}
335349

src/packages/frontend/frame-editors/time-travel-editor/actions.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,11 @@ export class TimeTravelActions extends CodeEditorActions<TimeTravelState> {
140140
if (this.syncdoc == null) return;
141141
this.syncdoc.on("change", debounce(this.syncdoc_changed, 1000));
142142
if (this.syncdoc.get_state() != "ready") {
143-
await once(this.syncdoc, "ready");
143+
try {
144+
await once(this.syncdoc, "ready");
145+
} catch {
146+
return;
147+
}
144148
}
145149
if (this.syncdoc == null) return;
146150
// cause initial load -- we could be plugging into an already loaded syncdoc,

src/packages/frontend/frame-editors/whiteboard-editor/elements/code/index.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,13 @@ export default function Code({
5454
const [mode, setMode] = useState<any>(codemirrorMode("py"));
5555
const isMountedRef = useIsMountedRef();
5656
useAsyncEffect(async () => {
57-
const mode = await getMode({ project_id, path });
57+
let mode;
58+
try {
59+
mode = await getMode({ project_id, path });
60+
} catch {
61+
// this can fail, e.g., if user closes file before finishing opening it
62+
return;
63+
}
5864
if (isMountedRef.current) {
5965
setMode(mode);
6066
}
@@ -100,7 +106,7 @@ export default function Code({
100106
if (elt == null) return;
101107
const h = Math.max(
102108
MIN_HEIGHT,
103-
elt.getBoundingClientRect()?.height / canvasScale + EXTRA_HEIGHT
109+
elt.getBoundingClientRect()?.height / canvasScale + EXTRA_HEIGHT,
104110
);
105111
actions.setElement({
106112
obj: { id: element.id, h },
@@ -116,7 +122,7 @@ export default function Code({
116122
if (elt == null) return;
117123
const newHeight = Math.max(
118124
MIN_HEIGHT,
119-
elt.getBoundingClientRect()?.height / canvasScale + EXTRA_HEIGHT
125+
elt.getBoundingClientRect()?.height / canvasScale + EXTRA_HEIGHT,
120126
);
121127
if (newHeight > element.h) {
122128
shrinkElement.cancel();

0 commit comments

Comments
 (0)