From af8d95cdb6d8cd2af5364ded38f61fe4f13bdf6b Mon Sep 17 00:00:00 2001 From: wangdl Date: Fri, 19 Jun 2026 12:18:46 +0800 Subject: [PATCH] fix: add try-catch + error logging to processBatch Prevents 500 from crashing the entire batch. Logs the actual error to server log for debugging. Co-Authored-By: Claude Opus 4.7 --- .../reading-event-processor.service.ts | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/src/modules/reading-event/reading-event-processor.service.ts b/src/modules/reading-event/reading-event-processor.service.ts index a032944..d9fada5 100644 --- a/src/modules/reading-event/reading-event-processor.service.ts +++ b/src/modules/reading-event/reading-event-processor.service.ts @@ -1,4 +1,4 @@ -import { Injectable } from '@nestjs/common'; +import { Injectable, Logger } from '@nestjs/common'; import { PrismaService } from '../../infrastructure/database/prisma.service'; import { LearningSessionRepository } from '../learning-session/learning-session.repository'; import { LearningActivityRepository } from '../learning-activity/learning-activity.repository'; @@ -36,6 +36,8 @@ interface ValidatedEvent { @Injectable() export class ReadingEventProcessorService { + private readonly logger = new Logger(ReadingEventProcessorService.name); + constructor( private readonly prisma: PrismaService, private readonly sessionRepo: LearningSessionRepository, @@ -51,13 +53,19 @@ export class ReadingEventProcessorService { const result: ProcessResult = { processed: 0, duplicate: 0, failed: 0, warnings: [] }; for (const e of events) { - const { outcome, warnings } = await this.processOne(userId, e); - switch (outcome) { - case 'processed': result.processed++; break; - case 'duplicate': result.duplicate++; break; - case 'failed': result.failed++; break; + try { + const { outcome, warnings } = await this.processOne(userId, e); + switch (outcome) { + case 'processed': result.processed++; break; + case 'duplicate': result.duplicate++; break; + case 'failed': result.failed++; break; + } + result.warnings.push(...warnings); + } catch (err: any) { + this.logger.error(`processOne failed for event ${e.eventId}: ${err.message}`, err.stack); + result.failed++; + result.warnings.push({ eventId: e.eventId, code: 'INTERNAL_ERROR', message: err.message }); } - result.warnings.push(...warnings); } return result;