diff --git a/backend/src/modules/ai/services/ocr.service.ts b/backend/src/modules/ai/services/ocr.service.ts index 6d57402b..6b8f6169 100644 --- a/backend/src/modules/ai/services/ocr.service.ts +++ b/backend/src/modules/ai/services/ocr.service.ts @@ -331,6 +331,19 @@ export class OcrService { }; } catch (err: unknown) { const durationMs = Date.now() - startTime; + // ดึง axios response body detail ออกมาด้วย (เช่น ไม่พบไฟล์: /mnt/uploads/...) + const axiosDetail = + err !== null && + typeof err === 'object' && + 'response' in err && + err.response !== null && + typeof err.response === 'object' && + 'data' in err.response && + err.response.data !== null && + typeof err.response.data === 'object' && + 'detail' in err.response.data + ? String((err.response.data as { detail: unknown }).detail) + : null; const cause = err instanceof AggregateError && err.errors?.length ? err.errors @@ -339,6 +352,9 @@ export class OcrService { : err instanceof Error ? err.message : String(err); + const fullCause = axiosDetail + ? `${cause} — sidecar detail: ${axiosDetail} (sidecarPath: ${sidecarPath})` + : `${cause} (sidecarPath: ${sidecarPath})`; await this.writeAuditLog({ documentPublicId: input.documentPublicId, @@ -347,11 +363,11 @@ export class OcrService { modelType: 'tesseract', status: AiAuditStatus.FAILED, processingTimeMs: durationMs, - errorMessage: cause, + errorMessage: fullCause, cacheHit: false, }); - throw new Error(`Tesseract OCR Sidecar failed: ${cause}`); + throw new Error(`Tesseract OCR Sidecar failed: ${fullCause}`); } } diff --git a/backend/src/modules/ai/services/sandbox-ocr-engine.service.ts b/backend/src/modules/ai/services/sandbox-ocr-engine.service.ts index 8ebbac80..fc4025b5 100644 --- a/backend/src/modules/ai/services/sandbox-ocr-engine.service.ts +++ b/backend/src/modules/ai/services/sandbox-ocr-engine.service.ts @@ -130,9 +130,25 @@ export class SandboxOcrEngineService { fallbackUsed: false, }; } catch (error: unknown) { + // ดึง axios response body detail ออกมาด้วย (เช่น ไม่พบไฟล์: /mnt/uploads/...) + const axiosDetail = + error !== null && + typeof error === 'object' && + 'response' in error && + error.response !== null && + typeof error.response === 'object' && + 'data' in error.response && + error.response.data !== null && + typeof error.response.data === 'object' && + 'detail' in error.response.data + ? String((error.response.data as { detail: unknown }).detail) + : null; const cause = error instanceof Error ? error.message : String(error); + const fullCause = axiosDetail + ? `${cause} — sidecar detail: ${axiosDetail}` + : cause; this.logger.warn( - `Typhoon OCR failed in sandbox, falling back to Tesseract: ${cause}` + `Typhoon OCR failed in sandbox, falling back to Tesseract: ${fullCause}` ); const fallbackResult = await this.ocrService.detectAndExtract({