Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | 309x 309x 3199x 3199x 3199x 3199x 3199x | import { useCallback, useState } from "react";
import { ErrorEmitter, GiveErrorEmitter } from "./ErrorEmitter";
type AllFunctionsCallerType<T extends any[] = any[]> = (...args: T) => void;
export type CallAll = <T extends any[]>(
...fns: Array<AllFunctionsCallerType<Array<T>> | null | undefined>
) => void;
type ComponentsTree = {
componentName: string;
child?: ComponentsTree | null;
};
interface ErrorInfo {
getComponentNameFromErrorStack: (
stack: string | undefined | null,
) => string[];
callAll: CallAll;
logError: (error: Error, info: React.ErrorInfo) => void;
ErrorEmitter: GiveErrorEmitter;
}
const parseErrorStack = (errorStack: string): ComponentsTree | null => {
const stackLines = errorStack.split("\n");
const componentRegex = /\sat\s(\S+)\s\((\S+\.js|\.tsx|\.ts):(\d+):(\d+)\)/;
let currentComponent: ComponentsTree | null = null;
for (const line of stackLines) {
const match = componentRegex.exec(line);
if (match) {
if (match[1] === "RenderedRoute") break;
const componentName = match[1];
const componentNode: ComponentsTree = {
componentName,
child: currentComponent,
};
currentComponent = componentNode;
}
}
return currentComponent;
};
export const useErrorUtilities = (): ErrorInfo => {
const [componentStack, setComponentStack] = useState<
string | null | undefined
>();
const callAll: CallAll = (...fns) =>
((...args) => {
fns.forEach((fn) => fn && fn(...args));
})();
const logError = (error: Error, info: React.ErrorInfo): void => {
setComponentStack(info.componentStack);
console.error("Error occurred:", error);
console.log("Error:", { err: info.componentStack });
console.groupCollapsed("Error details:");
console.log("Name:", error.name);
console.log("Message:", error.message);
getComponentNameFromErrorStack(info.componentStack);
console.groupEnd();
};
const getComponentNameFromErrorStack = useCallback(
(stack: string | undefined | null): string[] => {
if (!stack) return [];
const componentsTree = parseErrorStack(stack);
if (componentsTree) {
console.log("Feature Component:", componentsTree.componentName);
let component = componentsTree.child;
while (component?.child) {
component = component.child;
}
console.log("Crashing Component", component?.componentName);
}
return [];
},
[componentStack],
);
return {
getComponentNameFromErrorStack,
callAll,
logError,
ErrorEmitter: ErrorEmitter,
};
};
|