UNPKG

1.25 kBJavaScriptView Raw
1/**
2 * Find the closest error boundary to a thrown error and call it
3 * @param {object} error The thrown value
4 * @param {import('../internal').VNode} vnode The vnode that threw
5 * the error that was caught (except for unmounting when this parameter
6 * is the highest parent that was being unmounted)
7 * @param {import('../internal').VNode} [oldVNode]
8 * @param {import('../internal').ErrorInfo} [errorInfo]
9 */
10export function _catchError(error, vnode, oldVNode, errorInfo) {
11 /** @type {import('../internal').Component} */
12 let component, ctor, handled;
13
14 for (; (vnode = vnode._parent); ) {
15 if ((component = vnode._component) && !component._processingException) {
16 try {
17 ctor = component.constructor;
18
19 if (ctor && ctor.getDerivedStateFromError != null) {
20 component.setState(ctor.getDerivedStateFromError(error));
21 handled = component._dirty;
22 }
23
24 if (component.componentDidCatch != null) {
25 component.componentDidCatch(error, errorInfo || {});
26 handled = component._dirty;
27 }
28
29 // This is an error boundary. Mark it as having bailed out, and whether it was mid-hydration.
30 if (handled) {
31 return (component._pendingError = component);
32 }
33 } catch (e) {
34 error = e;
35 }
36 }
37 }
38
39 throw error;
40}