feat: in case of any error, avoid crashing the worker

This commit is contained in:
Nevo David 2025-07-21 12:44:02 +07:00
parent 56b78111a7
commit 5e7da34863
4 changed files with 53 additions and 93 deletions

View File

@ -1,6 +1,5 @@
import { Module } from '@nestjs/common';
import { StarsController } from './stars.controller';
import { DatabaseModule } from '@gitroom/nestjs-libraries/database/prisma/database.module';
import { TrendingService } from '@gitroom/nestjs-libraries/services/trending.service';
import { PostsController } from '@gitroom/workers/app/posts.controller';
@ -10,7 +9,6 @@ import { PlugsController } from '@gitroom/workers/app/plugs.controller';
@Module({
imports: [DatabaseModule, BullMqModule],
controllers: [
...(!process.env.IS_GENERAL ? [StarsController] : []),
PostsController,
PlugsController,
],

View File

@ -14,7 +14,14 @@ export class PlugsController {
totalRuns: number;
currentRun: number;
}) {
return this._integrationService.processPlugs(data);
try {
return await this._integrationService.processPlugs(data);
} catch (err) {
console.log(
"Unhandled error, let's avoid crashing the plugs worker",
err
);
}
}
@EventPattern('internal-plugs', Transport.REDIS)
@ -27,6 +34,13 @@ export class PlugsController {
delay: number;
information: any;
}) {
return this._integrationService.processInternalPlug(data);
try {
return await this._integrationService.processInternalPlug(data);
} catch (err) {
console.log(
"Unhandled error, let's avoid crashing the internal plugs worker",
err
);
}
}
}

View File

@ -18,31 +18,59 @@ export class PostsController {
try {
return await this._postsService.post(data.id);
} catch (err) {
console.log('Unhandled error, let\'s avoid crashing the worker', err);
console.log("Unhandled error, let's avoid crashing the post worker", err);
}
}
@EventPattern('submit', Transport.REDIS)
async payout(data: { id: string; releaseURL: string }) {
return this._postsService.payout(data.id, data.releaseURL);
try {
return await this._postsService.payout(data.id, data.releaseURL);
} catch (err) {
console.log(
"Unhandled error, let's avoid crashing the submit worker",
err
);
}
}
@EventPattern('sendDigestEmail', Transport.REDIS)
async sendDigestEmail(data: { subject: string; org: string; since: string }) {
return this._postsService.sendDigestEmail(
data.subject,
data.org,
data.since
);
try {
return await this._postsService.sendDigestEmail(
data.subject,
data.org,
data.since
);
} catch (err) {
console.log(
"Unhandled error, let's avoid crashing the digest worker",
err
);
}
}
@EventPattern('webhooks', Transport.REDIS)
async webhooks(data: { org: string; since: string }) {
return this._webhooksService.fireWebhooks(data.org, data.since);
try {
return await this._webhooksService.fireWebhooks(data.org, data.since);
} catch (err) {
console.log(
"Unhandled error, let's avoid crashing the webhooks worker",
err
);
}
}
@EventPattern('cron', Transport.REDIS)
async cron(data: { id: string }) {
return this._autopostsService.startAutopost(data.id);
try {
return await this._autopostsService.startAutopost(data.id);
} catch (err) {
console.log(
"Unhandled error, let's avoid crashing the autopost worker",
err
);
}
}
}

View File

@ -1,80 +0,0 @@
import { Controller } from '@nestjs/common';
import { EventPattern, Transport } from '@nestjs/microservices';
import { JSDOM } from 'jsdom';
import { StarsService } from '@gitroom/nestjs-libraries/database/prisma/stars/stars.service';
import { TrendingService } from '@gitroom/nestjs-libraries/services/trending.service';
import dayjs from 'dayjs';
@Controller()
export class StarsController {
constructor(
private _starsService: StarsService,
private _trendingService: TrendingService
) {}
@EventPattern('check_stars', Transport.REDIS)
async checkStars(data: { login: string }) {
// not to be affected by the limit, we scrape the HTML instead of using the API
const loadedHtml = await (
await fetch(`https://github.com/${data.login}`)
).text();
const dom = new JSDOM(loadedHtml);
const totalStars =
+dom.window.document
.querySelector('#repo-stars-counter-star')
?.getAttribute('title')
?.replace(/,/g, '') || 0;
const totalForks = +dom.window.document
.querySelector('#repo-network-counter')
?.getAttribute('title')
?.replace(/,/g, '');
const lastValue = await this._starsService.getLastStarsByLogin(data.login);
if (
dayjs(lastValue.date).format('YYYY-MM-DD') ===
dayjs().format('YYYY-MM-DD')
) {
console.log('stars already synced for today');
return;
}
const totalNewsStars = totalStars - (lastValue?.totalStars || 0);
const totalNewsForks = totalForks - (lastValue?.totalForks || 0);
// if there is no stars in the database, we need to sync the stars
if (!lastValue?.totalStars) {
return;
}
// if there is stars in the database, sync the new stars
return this._starsService.createStars(
data.login,
totalNewsStars,
totalStars,
totalNewsForks,
totalForks,
new Date()
);
}
@EventPattern('sync_all_stars', Transport.REDIS, { concurrency: 1 })
async syncAllStars(data: { login: string }) {
// if there is a sync in progress, it's better not to touch it
if (
data?.login &&
(await this._starsService.getStarsByLogin(data?.login)).length
) {
return;
}
const findValidToken = await this._starsService.findValidToken(data?.login);
await this._starsService.sync(data.login, findValidToken?.token);
}
@EventPattern('sync_trending', Transport.REDIS, { concurrency: 1 })
async syncTrending() {
return this._trendingService.syncTrending();
}
}