2021-11-08 10:30:36 +01:00
|
|
|
import type { ComponentNode } from "./component_node";
|
|
|
|
|
import type { Fiber } from "./fibers";
|
|
|
|
|
|
|
|
|
|
export const fibersInError: WeakMap<Fiber, Error> = new WeakMap();
|
|
|
|
|
export const nodeErrorHandlers: WeakMap<ComponentNode, ((error: Error) => void)[]> = new WeakMap();
|
|
|
|
|
|
2021-11-16 16:26:39 +01:00
|
|
|
function _handleError(node: ComponentNode | null, error: Error, isFirstRound = false): boolean {
|
2021-11-08 10:30:36 +01:00
|
|
|
if (!node) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
const fiber = node.fiber;
|
|
|
|
|
if (fiber) {
|
|
|
|
|
fibersInError.set(fiber, error);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const errorHandlers = nodeErrorHandlers.get(node);
|
|
|
|
|
if (errorHandlers) {
|
2021-11-16 16:26:39 +01:00
|
|
|
if (isFirstRound && fiber) {
|
2021-11-08 10:30:36 +01:00
|
|
|
fiber.root.counter--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let propagate = true;
|
|
|
|
|
for (const h of errorHandlers) {
|
|
|
|
|
try {
|
|
|
|
|
h(error);
|
|
|
|
|
propagate = false;
|
|
|
|
|
} catch (e) {
|
|
|
|
|
error = e as Error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (propagate) {
|
|
|
|
|
return _handleError(node.parent, error);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
} else {
|
|
|
|
|
return _handleError(node.parent, error);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function handleError(node: ComponentNode, error: Error) {
|
|
|
|
|
const fiber = node.fiber!;
|
|
|
|
|
fibersInError.set(fiber.root, error);
|
|
|
|
|
|
2021-11-16 16:26:39 +01:00
|
|
|
if (!_handleError(node, error, true)) {
|
2021-11-08 10:30:36 +01:00
|
|
|
try {
|
|
|
|
|
node.app.destroy();
|
|
|
|
|
} catch (e) {}
|
|
|
|
|
}
|
|
|
|
|
}
|