Skip to content
This repository was archived by the owner on Jul 4, 2025. It is now read-only.

Commit 00b5fe2

Browse files
fix: prevent error loop, create crash report file if not exist
1 parent c55cade commit 00b5fe2

File tree

5 files changed

+42
-12
lines changed

5 files changed

+42
-12
lines changed

cortex-js/src/command.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,17 @@ async function bootstrap() {
2424
process.exit(1);
2525
},
2626
});
27+
2728
telemetryUseCase = await app.resolve(TelemetryUsecases);
2829
contextService = await app.resolve(ContextService);
30+
2931
telemetryUseCase!.sendCrashReport();
30-
await contextService!.init(async () => CommandFactory.runApplication(app));
32+
33+
await contextService!.init(async () => {
34+
contextService!.set('source', TelemetrySource.CLI);
35+
return CommandFactory.runApplication(app);
36+
});
37+
3138
const notifier = updateNotifier({
3239
pkg: packageJson,
3340
updateCheckInterval: 1000 * 60 * 60, // 1 hour

cortex-js/src/infrastructure/middlewares/app.logger.middleware.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { TelemetrySource } from '@/domain/telemetry/telemetry.interface';
12
import { ContextService } from '@/util/context.service';
23
import { Injectable, NestMiddleware, Logger } from '@nestjs/common';
34

@@ -32,6 +33,7 @@ export class AppLoggerMiddleware implements NestMiddleware {
3233
});
3334
this.contextService.init(() => {
3435
this.contextService.set('endpoint', originalUrl ?? url);
36+
this.contextService.set('source', TelemetrySource.CORTEX_SERVER);
3537
next();
3638
});
3739
}

cortex-js/src/infrastructure/repositories/telemetry/telemetry.repository.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ export class TelemetryRepositoryImpl implements TelemetryRepository {
3333

3434
private async getTelemetryDirectory(): Promise<string> {
3535
const dataFolderPath = await this.fileManagerService.getDataFolderPath();
36+
await this.fileManagerService.createFolderIfNotExistInDataFolder(
37+
'telemetry',
38+
);
3639
return join(dataFolderPath, 'telemetry');
3740
}
3841

cortex-js/src/infrastructure/services/file-manager/file-manager.service.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ export class FileManagerService {
175175
stats.size === 0 ? data : `\n${data}`,
176176
{
177177
encoding: 'utf8',
178+
flag: 'a+',
178179
},
179180
);
180181
} catch (err) {

cortex-js/src/usecases/telemetry/telemetry.usecases.ts

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,29 +9,30 @@ import { HttpException, Inject, Injectable, Scope } from '@nestjs/common';
99

1010
@Injectable({ scope: Scope.TRANSIENT })
1111
export class TelemetryUsecases {
12+
private readonly crashReports: string[] = [];
13+
private readonly maxSize = 100;
14+
1215
constructor(
1316
@Inject('TELEMETRY_REPOSITORY')
1417
private readonly telemetryRepository: TelemetryRepository,
1518
private readonly contextService: ContextService,
1619
) {
17-
process.on('uncaughtException', async (error: Error) => {
18-
telemetryRepository.createCrashReport(this.buildCrashReport(error));
19-
});
20-
21-
process.on('unhandledRejection', async (error: Error) => {
22-
telemetryRepository.createCrashReport(this.buildCrashReport(error));
23-
});
20+
this.catchException();
2421
}
2522

2623
async createCrashReport(
2724
error: HttpException | Error,
2825
source: TelemetrySource,
2926
): Promise<void> {
3027
try {
31-
if (this.isCrashReportEnabled() === false) {
32-
return;
33-
}
28+
if (!this.isCrashReportEnabled()) return;
29+
3430
const crashReport: CrashReportAttributes = this.buildCrashReport(error);
31+
if (this.crashReports.includes(JSON.stringify(crashReport))) return;
32+
if (this.crashReports.length >= this.maxSize) {
33+
this.crashReports.shift();
34+
}
35+
this.crashReports.push(JSON.stringify(crashReport));
3536

3637
await this.telemetryRepository.createCrashReport(crashReport, source);
3738
} catch (e) {}
@@ -83,6 +84,22 @@ export class TelemetryUsecases {
8384
}
8485

8586
private isCrashReportEnabled(): boolean {
86-
return process.env.CORTEX_CRASH_REPORT === '1';
87+
return process.env.CORTEX_CRASH_REPORT !== '0';
88+
}
89+
90+
private async catchException(): Promise<void> {
91+
process.on('uncaughtException', async (error: Error) => {
92+
await this.createCrashReport(
93+
error,
94+
this.contextService.get('source') as TelemetrySource,
95+
);
96+
});
97+
98+
process.on('unhandledRejection', async (error: Error) => {
99+
await this.createCrashReport(
100+
error,
101+
this.contextService.get('source') as TelemetrySource,
102+
);
103+
});
87104
}
88105
}

0 commit comments

Comments
 (0)