From 5e7da348636d42fd3cb9a2dc0db3e67b508015d8 Mon Sep 17 00:00:00 2001 From: Nevo David Date: Mon, 21 Jul 2025 12:44:02 +0700 Subject: [PATCH] feat: in case of any error, avoid crashing the worker --- apps/workers/src/app/app.module.ts | 2 - apps/workers/src/app/plugs.controller.ts | 18 +++++- apps/workers/src/app/posts.controller.ts | 46 +++++++++++--- apps/workers/src/app/stars.controller.ts | 80 ------------------------ 4 files changed, 53 insertions(+), 93 deletions(-) delete mode 100644 apps/workers/src/app/stars.controller.ts diff --git a/apps/workers/src/app/app.module.ts b/apps/workers/src/app/app.module.ts index d008584a..6ce90700 100644 --- a/apps/workers/src/app/app.module.ts +++ b/apps/workers/src/app/app.module.ts @@ -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, ], diff --git a/apps/workers/src/app/plugs.controller.ts b/apps/workers/src/app/plugs.controller.ts index b4e3194c..f730323c 100644 --- a/apps/workers/src/app/plugs.controller.ts +++ b/apps/workers/src/app/plugs.controller.ts @@ -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 + ); + } } } diff --git a/apps/workers/src/app/posts.controller.ts b/apps/workers/src/app/posts.controller.ts index 19fe9b51..f41b77fc 100644 --- a/apps/workers/src/app/posts.controller.ts +++ b/apps/workers/src/app/posts.controller.ts @@ -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 + ); + } } } diff --git a/apps/workers/src/app/stars.controller.ts b/apps/workers/src/app/stars.controller.ts deleted file mode 100644 index c9b4c8d2..00000000 --- a/apps/workers/src/app/stars.controller.ts +++ /dev/null @@ -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(); - } -}