diff --git a/backend/src/modules/catalog-etl/schedulers/catalog-etl.scheduler.spec.ts b/backend/src/modules/catalog-etl/schedulers/catalog-etl.scheduler.spec.ts index 944d71f..67220dd 100644 --- a/backend/src/modules/catalog-etl/schedulers/catalog-etl.scheduler.spec.ts +++ b/backend/src/modules/catalog-etl/schedulers/catalog-etl.scheduler.spec.ts @@ -80,4 +80,16 @@ describe('CatalogEtlScheduler.scheduledTerminalEtl', () => { expect(mockRunStep).toHaveBeenCalledTimes(1); expect(mockRunStep).toHaveBeenCalledWith('terminals-sync'); }); + + it('logs error and does not throw when the skip guard throws', async () => { + mockGetLastSuccessfulStepRun.mockRejectedValueOnce( + new Error('db connection lost'), + ); + await expect(makeScheduler().scheduledTerminalEtl()).resolves.not.toThrow(); + expect(mockRunStep).not.toHaveBeenCalled(); + expect(mockLogger.error).toHaveBeenCalledWith( + expect.objectContaining({ err: expect.any(Error) }), + 'terminal ETL skip guard failed', + ); + }); }); diff --git a/backend/src/modules/catalog-etl/schedulers/catalog-etl.scheduler.ts b/backend/src/modules/catalog-etl/schedulers/catalog-etl.scheduler.ts index d873e7f..84a9765 100644 --- a/backend/src/modules/catalog-etl/schedulers/catalog-etl.scheduler.ts +++ b/backend/src/modules/catalog-etl/schedulers/catalog-etl.scheduler.ts @@ -15,39 +15,43 @@ export class CatalogEtlScheduler { @Cron('0 * * * *', { name: 'terminal-etl' }) async scheduledTerminalEtl(): Promise { - if (await this.shouldSkip('terminals-sync')) return; - this.logger.info('Starting scheduled terminal ETL'); - try { - await this.catalogEtlService.runStep('terminals-sync'); - } catch (err: unknown) { - if (err instanceof ConflictException) { - this.logger.debug( + if (await this.shouldSkip('terminals-sync')) return; + this.logger.info('Starting scheduled terminal ETL'); + + try { + await this.catalogEtlService.runStep('terminals-sync'); + } catch (err: unknown) { + if (err instanceof ConflictException) { + this.logger.debug( + { err }, + 'Scheduled terminal ETL skipped: ETL lock already held', + ); + return; + } + this.logger.error( { err }, - 'Scheduled terminal ETL skipped: ETL lock already held', + 'terminals-sync failed; skipping terminal-distances-sync', ); return; } - this.logger.error( - { err }, - 'terminals-sync failed; skipping terminal-distances-sync', - ); - return; - } - if (await this.shouldSkip('terminal-distances-sync')) return; + if (await this.shouldSkip('terminal-distances-sync')) return; - try { - await this.catalogEtlService.runStep('terminal-distances-sync'); - } catch (err: unknown) { - if (err instanceof ConflictException) { - this.logger.debug( - { err }, - 'terminal-distances-sync skipped: ETL lock already held', - ); - return; + try { + await this.catalogEtlService.runStep('terminal-distances-sync'); + } catch (err: unknown) { + if (err instanceof ConflictException) { + this.logger.debug( + { err }, + 'terminal-distances-sync skipped: ETL lock already held', + ); + return; + } + this.logger.error({ err }, 'terminal-distances-sync failed'); } - this.logger.error({ err }, 'terminal-distances-sync failed'); + } catch (err: unknown) { + this.logger.error({ err }, 'terminal ETL skip guard failed'); } }