-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrendererGlobalErrors.ts
More file actions
64 lines (57 loc) · 2.8 KB
/
rendererGlobalErrors.ts
File metadata and controls
64 lines (57 loc) · 2.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
const RESIZE_OBSERVER_LOOP_MESSAGES = new Set([
"ResizeObserver loop completed with undelivered notifications.",
"ResizeObserver loop limit exceeded",
]);
function readErrorMessage(error: unknown): string | null {
if (typeof error === "string") return error;
if (error instanceof Error) return error.message;
if (error && typeof error === "object" && "message" in error) {
const message = (error as { message?: unknown }).message;
return typeof message === "string" ? message : null;
}
return null;
}
function readErrorName(error: unknown): string | null {
if (error instanceof Error) return error.name;
if (error && typeof error === "object" && "name" in error) {
const name = (error as { name?: unknown }).name;
return typeof name === "string" ? name : null;
}
return null;
}
export function isResizeObserverLoopError(error: unknown): boolean {
const message = readErrorMessage(error);
return message !== null && RESIZE_OBSERVER_LOOP_MESSAGES.has(message);
}
// HeroUI/react-aria-components wraps toast queue updates in
// document.startViewTransition(). The ViewTransition's finished/ready/
// updateCallbackDone promises reject with AbortError "Transition was skipped"
// when a new transition supersedes the previous one (e.g. closing a toast
// while another is animating). HeroUI does not attach handlers, so the
// rejection bubbles to window. It is benign — the DOM update still ran via
// flushSync — and must not be treated as a renderer crash.
export function isViewTransitionSkippedError(error: unknown): boolean {
const name = readErrorName(error);
if (name !== "AbortError") return false;
const message = readErrorMessage(error);
return message === "Transition was skipped";
}
// Sibling of `isViewTransitionSkippedError`: when the document state changes
// in a way that invalidates the snapshot mid-transition (e.g. the Settings
// overlay closes while a button-press transition is mid-flight, or the
// terminal panel opens and reflows the tree), Chromium rejects the
// ViewTransition promises with InvalidStateError "Transition was aborted
// because of invalid state" instead of the AbortError variant. Same root
// cause, same benign treatment — the DOM update still completed.
export function isViewTransitionInvalidStateError(error: unknown): boolean {
const name = readErrorName(error);
if (name !== "InvalidStateError") return false;
const message = readErrorMessage(error);
return message === "Transition was aborted because of invalid state";
}
export function isIgnorableWindowError(event: ErrorEvent): boolean {
return isResizeObserverLoopError(event.error) || isResizeObserverLoopError(event.message);
}
export function isIgnorableRejection(reason: unknown): boolean {
return isViewTransitionSkippedError(reason) || isViewTransitionInvalidStateError(reason);
}