From f2bd6eb663de79adb764abdc6269ac6287343029 Mon Sep 17 00:00:00 2001 From: Adam Refaey Date: Wed, 23 Apr 2025 22:10:38 +0200 Subject: [PATCH 1/3] fix: Enhance error handling and add debug message support in report processing --- .../document-processor.controller.ts | 78 ++++++++++++++----- backend/src/reports/models/report.model.ts | 3 + frontend/src/common/models/medicalReport.ts | 1 + 3 files changed, 61 insertions(+), 21 deletions(-) diff --git a/backend/src/document-processor/controllers/document-processor.controller.ts b/backend/src/document-processor/controllers/document-processor.controller.ts index c705dc3a..c4e217b7 100644 --- a/backend/src/document-processor/controllers/document-processor.controller.ts +++ b/backend/src/document-processor/controllers/document-processor.controller.ts @@ -182,20 +182,41 @@ export class DocumentProcessorController { this.logger.log(`Started async processing for report: ${reportId}`); // Get the file from S3 - const fileBuffer = await this.getFileFromS3(filePath); + let fileBuffer; + try { + fileBuffer = await this.getFileFromS3(filePath); + this.logger.log(`Successfully retrieved file from S3 for report: ${reportId}`); + } catch (error) { + this.logger.error( + `Failed to retrieve file from S3 for report ${reportId}: ${error instanceof Error ? error.message : 'Unknown error'}`, + ); + await this.updateReportStatus(reportId, userId, ProcessingStatus.FAILED); + return; + } // Process the document - const result = await this.documentProcessorService.processDocument(fileBuffer, userId); + let result; + try { + result = await this.documentProcessorService.processDocument(fileBuffer, userId); + this.logger.log(`Successfully processed document for report: ${reportId}`); + } catch (error) { + this.logger.error( + `Failed to process document for report ${reportId}: ${error instanceof Error ? error.message : 'Unknown error'}`, + ); + await this.updateReportStatus(reportId, userId, ProcessingStatus.FAILED); + return; + } // Fetch the report again to ensure we have the latest version const report = await this.reportsService.findOne(reportId, userId); if (!report) { - throw new Error(`Report ${reportId} not found during async processing`); + this.logger.error(`Report ${reportId} not found during async processing`); + return; } // Update the report with analysis results - report.title = result.analysis.title || 'Untitled Report'; - report.category = result.analysis.category || 'general'; + report.title = result.analysis.title; + report.category = result.analysis.category; report.processingStatus = ProcessingStatus.PROCESSED; // Extract lab values @@ -214,25 +235,40 @@ export class DocumentProcessorController { this.logger.log(`Completed async processing for report: ${reportId}`); } catch (error) { // If processing fails, update the report status to indicate failure - try { - const report = await this.reportsService.findOne(reportId, userId); - if (report) { - report.processingStatus = ProcessingStatus.FAILED; - report.updatedAt = new Date().toISOString(); - await this.reportsService.updateReport(report); - } - } catch (updateError: unknown) { - this.logger.error( - `Failed to update report status after processing error: ${ - updateError instanceof Error ? updateError.message : 'Unknown error' - }`, - ); - } - this.logger.error( `Error during async processing for report ${reportId}: ${error instanceof Error ? error.message : 'Unknown error'}`, ); - throw error; + await this.updateReportStatus(reportId, userId, ProcessingStatus.FAILED); + } + } + + /** + * Updates a report's processing status + * @param reportId - ID of the report to update + * @param userId - ID of the user who owns the report + * @param status - The new processing status + */ + private async updateReportStatus( + reportId: string, + userId: string, + status: ProcessingStatus, + debugMessage: string | undefined = undefined, + ): Promise { + try { + const report = await this.reportsService.findOne(reportId, userId); + if (report) { + report.processingStatus = status; + report.updatedAt = new Date().toISOString(); + report.debugMessage = debugMessage; + await this.reportsService.updateReport(report); + this.logger.log(`Updated status of report ${reportId} to ${status}`); + } + } catch (updateError: unknown) { + this.logger.error( + `Failed to update report status after processing error: ${ + updateError instanceof Error ? updateError.message : 'Unknown error' + }`, + ); } } diff --git a/backend/src/reports/models/report.model.ts b/backend/src/reports/models/report.model.ts index aab7bc7c..45aff23f 100644 --- a/backend/src/reports/models/report.model.ts +++ b/backend/src/reports/models/report.model.ts @@ -74,4 +74,7 @@ export class Report { @ApiProperty({ description: 'Last update timestamp' }) updatedAt: string; + + @ApiProperty({ description: 'Optional debug message for the report' }) + debugMessage?: string; } diff --git a/frontend/src/common/models/medicalReport.ts b/frontend/src/common/models/medicalReport.ts index 1ee0d711..c2e05c15 100644 --- a/frontend/src/common/models/medicalReport.ts +++ b/frontend/src/common/models/medicalReport.ts @@ -58,4 +58,5 @@ export interface MedicalReport { fileSize: number; createdAt: string; // ISO date string updatedAt: string; // ISO date string + debugMessage?: string; // Optional debug message for the report } From 763a383b9733740d9f3ba8eca1eee946687a45a3 Mon Sep 17 00:00:00 2001 From: Adam Refaey Date: Wed, 23 Apr 2025 22:23:05 +0200 Subject: [PATCH 2/3] fix: Improve error handling in report processing and update report status logic --- .../document-processor.controller.ts | 28 ++++++++----------- .../utils/i18n/resources/en/reportDetail.json | 2 +- .../src/pages/Reports/ReportDetailPage.scss | 2 +- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/backend/src/document-processor/controllers/document-processor.controller.ts b/backend/src/document-processor/controllers/document-processor.controller.ts index c4e217b7..36aea1ec 100644 --- a/backend/src/document-processor/controllers/document-processor.controller.ts +++ b/backend/src/document-processor/controllers/document-processor.controller.ts @@ -187,10 +187,9 @@ export class DocumentProcessorController { fileBuffer = await this.getFileFromS3(filePath); this.logger.log(`Successfully retrieved file from S3 for report: ${reportId}`); } catch (error) { - this.logger.error( - `Failed to retrieve file from S3 for report ${reportId}: ${error instanceof Error ? error.message : 'Unknown error'}`, - ); - await this.updateReportStatus(reportId, userId, ProcessingStatus.FAILED); + const errorMessage = `Failed to retrieve file from S3 for report ${reportId}: ${error instanceof Error ? error.message : 'Unknown error'}`; + this.logger.error(errorMessage); + await this.failReport(reportId, userId, errorMessage); return; } @@ -200,10 +199,9 @@ export class DocumentProcessorController { result = await this.documentProcessorService.processDocument(fileBuffer, userId); this.logger.log(`Successfully processed document for report: ${reportId}`); } catch (error) { - this.logger.error( - `Failed to process document for report ${reportId}: ${error instanceof Error ? error.message : 'Unknown error'}`, - ); - await this.updateReportStatus(reportId, userId, ProcessingStatus.FAILED); + const errorMessage = `Failed to process document for report ${reportId}: ${error instanceof Error ? error.message : 'Unknown error'}`; + this.logger.error(errorMessage); + await this.failReport(reportId, userId, errorMessage); return; } @@ -235,10 +233,9 @@ export class DocumentProcessorController { this.logger.log(`Completed async processing for report: ${reportId}`); } catch (error) { // If processing fails, update the report status to indicate failure - this.logger.error( - `Error during async processing for report ${reportId}: ${error instanceof Error ? error.message : 'Unknown error'}`, - ); - await this.updateReportStatus(reportId, userId, ProcessingStatus.FAILED); + const errorMessage = `Error during async processing for report ${reportId}: ${error instanceof Error ? error.message : 'Unknown error'}`; + this.logger.error(errorMessage); + await this.failReport(reportId, userId, errorMessage); } } @@ -248,20 +245,19 @@ export class DocumentProcessorController { * @param userId - ID of the user who owns the report * @param status - The new processing status */ - private async updateReportStatus( + private async failReport( reportId: string, userId: string, - status: ProcessingStatus, debugMessage: string | undefined = undefined, ): Promise { try { const report = await this.reportsService.findOne(reportId, userId); if (report) { - report.processingStatus = status; + report.processingStatus = ProcessingStatus.FAILED; report.updatedAt = new Date().toISOString(); report.debugMessage = debugMessage; await this.reportsService.updateReport(report); - this.logger.log(`Updated status of report ${reportId} to ${status}`); + this.logger.log(`Updated status of report ${reportId} to FAILED`); } } catch (updateError: unknown) { this.logger.error( diff --git a/frontend/src/common/utils/i18n/resources/en/reportDetail.json b/frontend/src/common/utils/i18n/resources/en/reportDetail.json index 9aa87d6c..c26a6444 100644 --- a/frontend/src/common/utils/i18n/resources/en/reportDetail.json +++ b/frontend/src/common/utils/i18n/resources/en/reportDetail.json @@ -90,4 +90,4 @@ "original-report": "Original Report" } } -} \ No newline at end of file +} diff --git a/frontend/src/pages/Reports/ReportDetailPage.scss b/frontend/src/pages/Reports/ReportDetailPage.scss index 48861b05..5e1eacce 100644 --- a/frontend/src/pages/Reports/ReportDetailPage.scss +++ b/frontend/src/pages/Reports/ReportDetailPage.scss @@ -204,7 +204,7 @@ } &__section-empty-icon { - background-color: #EEF1FF; + background-color: #eef1ff; border-radius: 50%; width: 90px; height: 90px; From 97a4f5b81a57bf858214ac26743169afe70af50a Mon Sep 17 00:00:00 2001 From: Adam Refaey <5170324+adamrefaey@users.noreply.github.com> Date: Wed, 23 Apr 2025 22:25:25 +0200 Subject: [PATCH 3/3] Update backend/src/document-processor/controllers/document-processor.controller.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../controllers/document-processor.controller.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/document-processor/controllers/document-processor.controller.ts b/backend/src/document-processor/controllers/document-processor.controller.ts index 36aea1ec..e0c8ed8a 100644 --- a/backend/src/document-processor/controllers/document-processor.controller.ts +++ b/backend/src/document-processor/controllers/document-processor.controller.ts @@ -240,10 +240,10 @@ export class DocumentProcessorController { } /** - * Updates a report's processing status + * Updates a report's processing status to FAILED and logs a debug message * @param reportId - ID of the report to update * @param userId - ID of the user who owns the report - * @param status - The new processing status + * @param debugMessage - Optional debug message describing the failure */ private async failReport( reportId: string,