@memberjunction/react-runtime
Version:
Platform-agnostic React component runtime for MemberJunction. Provides core compilation, registry, and execution capabilities for React components in any JavaScript environment.
205 lines • 7.43 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ComponentErrorAnalyzer = void 0;
class ComponentErrorAnalyzer {
static identifyFailedComponents(errors) {
const failedComponents = new Set();
for (const error of errors) {
const components = this.extractComponentsFromError(error);
components.forEach(comp => failedComponents.add(comp));
}
return Array.from(failedComponents);
}
static analyzeComponentErrors(errors) {
const failures = [];
for (const error of errors) {
const failureInfo = this.analyzeError(error);
failures.push(...failureInfo);
}
const uniqueFailures = new Map();
failures.forEach(failure => {
const key = `${failure.componentName}-${failure.errorType}`;
if (!uniqueFailures.has(key)) {
uniqueFailures.set(key, failure);
}
});
return Array.from(uniqueFailures.values());
}
static extractComponentsFromError(error) {
const components = [];
for (const errorPattern of this.ERROR_PATTERNS) {
const match = error.match(errorPattern.pattern);
if (match) {
const componentName = errorPattern.extractComponent(match);
if (componentName && this.isLikelyComponentName(componentName)) {
components.push(componentName);
}
}
}
const stackComponents = this.extractComponentsFromStackTrace(error);
components.push(...stackComponents);
return components;
}
static analyzeError(error) {
const failures = [];
for (const errorPattern of this.ERROR_PATTERNS) {
const match = error.match(errorPattern.pattern);
if (match) {
const componentName = errorPattern.extractComponent(match);
if (componentName && this.isLikelyComponentName(componentName)) {
failures.push({
componentName,
errorType: errorPattern.errorType,
errorMessage: error,
lineNumber: this.extractLineNumber(error),
context: this.extractContext(error)
});
}
}
}
if (failures.length === 0) {
const stackComponents = this.extractComponentsFromStackTrace(error);
stackComponents.forEach(componentName => {
failures.push({
componentName,
errorType: 'unknown',
errorMessage: error,
lineNumber: this.extractLineNumber(error)
});
});
}
return failures;
}
static extractComponentsFromStackTrace(error) {
const components = [];
const stackPatterns = [
/at (\w+Component\w*)/g,
/at (\w+)\s*\(/g,
/in (\w+)\s*\(at/g,
/in (\w+)\s*\(created by/g
];
for (const pattern of stackPatterns) {
let match;
while ((match = pattern.exec(error)) !== null) {
const name = match[1];
if (this.isLikelyComponentName(name)) {
components.push(name);
}
}
}
return [...new Set(components)];
}
static isLikelyComponentName(name) {
const jsBuiltins = new Set([
'Object', 'Array', 'String', 'Number', 'Boolean', 'Function',
'Promise', 'Error', 'TypeError', 'ReferenceError', 'SyntaxError',
'undefined', 'null', 'console', 'window', 'document'
]);
const nonComponents = new Set([
'render', 'setState', 'forceUpdate', 'props', 'state', 'context',
'componentDidMount', 'componentWillUnmount', 'useEffect', 'useState'
]);
return (name.length > 0 &&
/^[A-Z]/.test(name) &&
!jsBuiltins.has(name) &&
!nonComponents.has(name) &&
!/^use[A-Z]/.test(name));
}
static extractLineNumber(error) {
const patterns = [
/:(\d+):\d+/,
/line (\d+)/i,
/Line (\d+)/
];
for (const pattern of patterns) {
const match = error.match(pattern);
if (match) {
return parseInt(match[1], 10);
}
}
return undefined;
}
static extractContext(error) {
const fileMatch = error.match(/\(at ([^)]+)\)/);
if (fileMatch) {
return fileMatch[1];
}
const createdByMatch = error.match(/created by (\w+)/);
if (createdByMatch) {
return `Created by ${createdByMatch[1]}`;
}
return undefined;
}
static formatAnalysisResults(failures) {
if (failures.length === 0) {
return 'No component failures detected';
}
let result = `Detected ${failures.length} component failure(s):\n`;
failures.forEach((failure, index) => {
result += `\n${index + 1}. Component: ${failure.componentName}\n`;
result += ` Error Type: ${failure.errorType}\n`;
if (failure.lineNumber) {
result += ` Line: ${failure.lineNumber}\n`;
}
if (failure.context) {
result += ` Context: ${failure.context}\n`;
}
result += ` Message: ${failure.errorMessage.substring(0, 200)}${failure.errorMessage.length > 200 ? '...' : ''}\n`;
});
return result;
}
}
exports.ComponentErrorAnalyzer = ComponentErrorAnalyzer;
ComponentErrorAnalyzer.ERROR_PATTERNS = [
{
pattern: /ReferenceError: (\w+) is not defined/,
errorType: 'not_defined',
extractComponent: (match) => match[1]
},
{
pattern: /Cannot read propert(?:y|ies) '(\w+)' of undefined/,
errorType: 'property_error',
extractComponent: (match) => match[1]
},
{
pattern: /(\w+)\(\.\.\.\): Nothing was returned from render/,
errorType: 'render_error',
extractComponent: (match) => match[1]
},
{
pattern: /at (\w+Component\w*)/,
errorType: 'stack_trace',
extractComponent: (match) => match[1]
},
{
pattern: /Error: Unable to find node on an unmounted component/,
errorType: 'unmounted_component',
extractComponent: () => null
},
{
pattern: /Invalid hook call.*component (\w+)/,
errorType: 'invalid_hook',
extractComponent: (match) => match[1]
},
{
pattern: /TypeError:.*in (\w+) \(at/,
errorType: 'type_error',
extractComponent: (match) => match[1]
},
{
pattern: /Module not found: Error: Can't resolve '\.\/(\w+)'/,
errorType: 'missing_import',
extractComponent: (match) => match[1]
},
{
pattern: /(\w+) is not a function/,
errorType: 'not_a_function',
extractComponent: (match) => match[1]
},
{
pattern: /Minified React error.*Visit.*for the full message.*component[: ](\w+)/s,
errorType: 'react_error',
extractComponent: (match) => match[1]
}
];
//# sourceMappingURL=component-error-analyzer.js.map