Skip to content

Commit 9ee179b

Browse files
authored
fix: Cluster processing failed (#128)
* fix: err message exception
1 parent fe2ea46 commit 9ee179b

File tree

5 files changed

+120
-46
lines changed

5 files changed

+120
-46
lines changed

ts-parser/src/parser/ModuleParser.ts

Lines changed: 60 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -103,43 +103,73 @@ export class ModuleParser {
103103

104104
private extractImports(sourceFile: SourceFile, _modulePath: string): Array<{ Path: string }> {
105105
const imports: Array<{ Path: string }> = [];
106-
107-
// Track unique import paths to avoid duplicates
108106
const uniquePaths = new Set<string>();
109-
110-
// Import declarations
111-
const importDeclarations = sourceFile.getImportDeclarations();
112-
for (const importDecl of importDeclarations) {
113-
const originalPath = importDecl.getModuleSpecifierValue();
114-
const resolvedPath = importDecl.getModuleSpecifierSourceFile()?.getFilePath();
115-
if (resolvedPath) {
116-
const relativePath = path.relative(this.projectRoot, resolvedPath);
117-
118-
if(uniquePaths.has(relativePath)) {
119-
continue;
107+
108+
// Safely process import declarations
109+
try {
110+
const importDeclarations = sourceFile.getImportDeclarations();
111+
for (const importDecl of importDeclarations) {
112+
try {
113+
const originalPath = importDecl.getModuleSpecifierValue();
114+
if (!originalPath) continue;
115+
116+
const resolvedPathMaybe = importDecl.getModuleSpecifierSourceFile()?.getFilePath();
117+
if (typeof resolvedPathMaybe === 'string') {
118+
const relativePath = path.relative(this.projectRoot, resolvedPathMaybe);
119+
if (!uniquePaths.has(relativePath)) {
120+
uniquePaths.add(relativePath);
121+
imports.push({ Path: relativePath });
122+
}
123+
} else {
124+
const externalPath = `external:${originalPath}`;
125+
if (!uniquePaths.has(externalPath)) {
126+
uniquePaths.add(externalPath);
127+
imports.push({ Path: externalPath });
128+
}
129+
}
130+
} catch (error) {
131+
console.warn(`[Worker ${process.pid}] Skipping problematic import in ${sourceFile.getFilePath()}:`, error);
120132
}
121-
uniquePaths.add(relativePath);
122-
imports.push({ Path: relativePath });
123-
} else {
124-
imports.push({ Path: "external:" + originalPath });
125133
}
134+
} catch (error) {
135+
console.error(`[Worker ${process.pid}] Failed to process import declarations in ${sourceFile.getFilePath()}:`, error);
126136
}
127-
128-
// Export declarations (re-exports)
129-
const exportDeclarations = sourceFile.getExportDeclarations();
130-
for (const exportDecl of exportDeclarations) {
131-
const originalPath = exportDecl.getModuleSpecifierValue();
132-
if (originalPath) {
133-
const resolvedPath = exportDecl.getModuleSpecifierSourceFile()?.getFilePath();
134-
if (resolvedPath) {
135-
const relativePath = path.relative(this.projectRoot, resolvedPath);
136-
imports.push({ Path: relativePath });
137-
} else {
138-
imports.push({ Path: "external:" + originalPath });
137+
138+
// Safely process export declarations
139+
try {
140+
const exportDeclarations = sourceFile.getExportDeclarations();
141+
for (const exportDecl of exportDeclarations) {
142+
try {
143+
const specNode = exportDecl.getModuleSpecifier();
144+
if (!specNode) continue;
145+
146+
const originalPath = specNode.getLiteralText?.() ?? specNode.getText?.() ?? '';
147+
if (!originalPath) continue;
148+
149+
const sourceFileObj = exportDecl.getModuleSpecifierSourceFile();
150+
const resolvedPathMaybe = sourceFileObj ? sourceFileObj.getFilePath() : undefined;
151+
152+
if (typeof resolvedPathMaybe === 'string') {
153+
const relativePath = path.relative(this.projectRoot, resolvedPathMaybe);
154+
if (!uniquePaths.has(relativePath)) {
155+
uniquePaths.add(relativePath);
156+
imports.push({ Path: relativePath });
157+
}
158+
} else {
159+
const externalPath = `external:${originalPath}`;
160+
if (!uniquePaths.has(externalPath)) {
161+
uniquePaths.add(externalPath);
162+
imports.push({ Path: externalPath });
163+
}
164+
}
165+
} catch (error) {
166+
console.warn(`[Worker ${process.pid}] Skipping problematic export in ${sourceFile.getFilePath()}:`, error);
139167
}
140168
}
169+
} catch (error) {
170+
console.error(`[Worker ${process.pid}] Failed to process export declarations in ${sourceFile.getFilePath()}:`, error);
141171
}
172+
142173
return imports;
143174
}
144-
145175
}

ts-parser/src/parser/RepositoryParser.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,8 +161,12 @@ export class RepositoryParser {
161161
const result = await processPackagesWithCluster(packages, this.projectRoot, options);
162162

163163
if (!result.success) {
164+
const errorMessages = result.errors.map((e, index) => {
165+
const message = e.message || 'Unknown error';
166+
return `Error ${index + 1}: ${message}`;
167+
}).join(', ');
164168
throw new Error(
165-
`Cluster processing failed: ${result.errors.map(e => e.message).join(', ')}`
169+
`Cluster processing failed: ${errorMessages}`
166170
);
167171
}
168172

ts-parser/src/utils/cluster-processor.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,31 @@ export function processPackagesWithCluster(
169169
for (const result of message.results) {
170170
results.push(result);
171171
if (!result.success && result.error) {
172-
errors.push(result.error);
172+
const err: unknown = result.error as unknown;
173+
let normalizedError: Error | null = null;
174+
175+
if (err instanceof Error) {
176+
normalizedError = err;
177+
} else if (typeof err === 'object' && err !== null) {
178+
const maybe = err as { message?: string; stack?: string; name?: string };
179+
const pkgName = (result as any).packageInfo?.name || (result as any).packageInfo?.path;
180+
const msg = (maybe.message && String(maybe.message)) || `Worker error${pkgName ? ` in ${pkgName}` : ''}`;
181+
normalizedError = new Error(msg);
182+
if (maybe.stack) {
183+
(normalizedError as any).stack = maybe.stack;
184+
}
185+
if (maybe.name) {
186+
(normalizedError as any).name = maybe.name;
187+
}
188+
} else if (typeof err === 'string') {
189+
normalizedError = new Error(err);
190+
}
191+
192+
if (normalizedError) {
193+
errors.push(normalizedError);
194+
} else {
195+
errors.push(new Error('Unknown worker error'));
196+
}
173197
}
174198
}
175199
}
@@ -195,6 +219,8 @@ export function processPackagesWithCluster(
195219
if (workerInfo?.currentBatch) {
196220
console.error(`Worker ${workerPid} (ID: ${workerId}) exited unexpectedly while processing batch. Re-queueing.`);
197221
packagesToProcessQueue.unshift(workerInfo.currentBatch);
222+
// Add an error to the errors array for this unexpected exit
223+
errors.push(new Error(`Worker ${workerPid} (ID: ${workerId}) exited unexpectedly while processing batch`));
198224
}
199225

200226
// Try to launch new workers if there are batches and capacity

ts-parser/src/utils/cluster-worker.ts

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ export function handleWorkerProcess(): void {
3030
const processor = new PackageProcessor(projectRoot);
3131
const workerResults: PackageProcessingResult[] = [];
3232

33-
for (const pkg of packages) {
34-
try {
35-
const result = await processor.processPackage(pkg, options);
36-
workerResults.push(result);
33+
for (const pkg of packages) {
34+
try {
35+
const result = await processor.processPackage(pkg, options);
36+
workerResults.push(result);
3737

3838
if (result.success) {
3939
console.log(`Worker ${process.pid} finished processing package ${pkg.name || pkg.path}`);
@@ -43,27 +43,41 @@ export function handleWorkerProcess(): void {
4343
} catch (error) {
4444
console.error(`Worker ${process.pid} error processing package ${pkg.name || pkg.path}:`, error);
4545

46+
// Ensure error is an instance of Error
47+
const processedError = error instanceof Error ? error : new Error(String(error));
48+
4649
// Add failed result
4750
workerResults.push({
4851
success: false,
49-
error: error as Error,
52+
error: processedError,
5053
packageInfo: {
5154
name: pkg.name || pkg.path,
5255
path: pkg.path,
5356
fileCount: 0,
5457
size: 0,
5558
},
5659
});
57-
}
5860
}
61+
}
5962

60-
if (process.send) {
61-
const response: WorkerResult = {
62-
results: workerResults,
63-
workerId: process.pid || 0,
64-
};
65-
process.send(response);
66-
}
63+
if (process.send) {
64+
const serializedResults = workerResults.map(r => ({
65+
...r,
66+
error: r.error
67+
? {
68+
message: (r.error as Error).message,
69+
stack: (r.error as Error).stack,
70+
name: (r.error as Error).name,
71+
}
72+
: undefined,
73+
}));
74+
75+
const response: WorkerResult = {
76+
results: serializedResults as unknown as PackageProcessingResult[],
77+
workerId: process.pid || 0,
78+
};
79+
process.send(response);
80+
}
6781

6882
console.log(`Worker ${process.pid} finished current batch, awaiting next task or shutdown signal.`);
6983
});

ts-parser/src/utils/package-processor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export interface PackageProcessingResult {
1919
module?: Module;
2020
repository?: Repository;
2121
outputPath?: string;
22-
error?: Error;
22+
error?: Error | { message?: string; stack?: string; name?: string };
2323
packageInfo: {
2424
name: string;
2525
path: string;

0 commit comments

Comments
 (0)