From 9f58efb851de0b441ffedcb90ca8c1cfa6ef2839 Mon Sep 17 00:00:00 2001 From: lebaudantoine Date: Mon, 2 Feb 2026 23:42:49 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=A5=85(summary)=20catch=20file-related=20?= =?UTF-8?q?exceptions=20when=20handling=20recording=20objects?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, if a recording file was not found in the bucket, the code would crash. This adds proper error handling to avoid unhandled failures. --- CHANGELOG.md | 1 + src/summary/summary/core/celery_worker.py | 59 ++++++++++++----------- src/summary/summary/core/file_service.py | 12 +++++ 3 files changed, 45 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 00e8daa3..d71d983c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ and this project adheres to - ♿️(frontend) sr pin/unpin announcements with dedicated messages #898 - ♿(frontend) adjust sr announcements for idle disconnect timer #908 - ♿️(frontend) add global screen reader announcer#922 +- 🥅(summary) catch file-related exceptions when handling recording #944 ### Fixed diff --git a/src/summary/summary/core/celery_worker.py b/src/summary/summary/core/celery_worker.py index 013f1b0e..91da516c 100644 --- a/src/summary/summary/core/celery_worker.py +++ b/src/summary/summary/core/celery_worker.py @@ -16,7 +16,7 @@ from urllib3.util import Retry from summary.core.analytics import MetadataManager, get_analytics from summary.core.config import get_settings -from summary.core.file_service import FileService +from summary.core.file_service import FileService, FileServiceException from summary.core.llm_service import LLMException, LLMObservability, LLMService from summary.core.prompt import ( FORMAT_NEXT_STEPS, @@ -145,36 +145,41 @@ def process_audio_transcribe_summarize_v2( max_retries=settings.whisperx_max_retries, ) - with ( - file_service.prepare_audio_file(filename) as (audio_file, metadata), - ): - metadata_manager.track(task_id, {"audio_length": metadata["duration"]}) + try: + with ( + file_service.prepare_audio_file(filename) as (audio_file, metadata), + ): + metadata_manager.track(task_id, {"audio_length": metadata["duration"]}) - if language is None: - language = settings.whisperx_default_language - logger.info( - "No language specified, using default from settings: %s", - (language or "auto-detect"), - ) - else: - logger.info( - "Querying transcription in '%s' language", - language, + if language is None: + language = settings.whisperx_default_language + logger.info( + "No language specified, using default from settings: %s", + (language or "auto-detect"), + ) + else: + logger.info( + "Querying transcription in '%s' language", + language, + ) + + transcription_start_time = time.time() + + transcription = whisperx_client.audio.transcriptions.create( + model=settings.whisperx_asr_model, file=audio_file, language=language ) - transcription_start_time = time.time() + transcription_time = round(time.time() - transcription_start_time, 2) + metadata_manager.track( + task_id, + {"transcription_time": transcription_time}, + ) + logger.info("Transcription received in %.2f seconds.", transcription_time) + logger.debug("Transcription: \n %s", transcription) - transcription = whisperx_client.audio.transcriptions.create( - model=settings.whisperx_asr_model, file=audio_file, language=language - ) - - transcription_time = round(time.time() - transcription_start_time, 2) - metadata_manager.track( - task_id, - {"transcription_time": transcription_time}, - ) - logger.info("Transcription received in %.2f seconds.", transcription_time) - logger.debug("Transcription: \n %s", transcription) + except FileServiceException: + logger.exception("Unexpected error for filename: %s", filename) + return metadata_manager.track_transcription_metadata(task_id, transcription) diff --git a/src/summary/summary/core/file_service.py b/src/summary/summary/core/file_service.py index 51622387..e42e193a 100644 --- a/src/summary/summary/core/file_service.py +++ b/src/summary/summary/core/file_service.py @@ -8,12 +8,19 @@ from pathlib import Path import mutagen from minio import Minio +from minio.error import MinioException, S3Error from summary.core.config import get_settings settings = get_settings() +class FileServiceException(Exception): + """Base exception for file service operations.""" + + pass + + class FileService: """Service for downloading and preparing files from MinIO storage.""" @@ -79,6 +86,11 @@ class FileService: return local_path + except (MinioException, S3Error) as e: + raise FileServiceException( + "Unexpected error while downloading object." + ) from e + finally: if response: response.close()