diff --git a/src/utils/files.py b/src/utils/files.py index d905ce30..d00399db 100644 --- a/src/utils/files.py +++ b/src/utils/files.py @@ -11,6 +11,7 @@ from typing import Any, Protocol from fastapi import UploadFile from nanoid import generate as generate_nanoid from openai import APIError +import sentry_sdk from sqlalchemy import Integer, select from sqlalchemy.ext.asyncio import AsyncSession @@ -165,6 +166,7 @@ class AudioProcessor: content_type=normalized_content_type, ) except APIError as exc: + sentry_sdk.capture_exception(exc) raise FileProcessingError("Audio transcription failed") from exc return ExtractedFileText( text=text, @@ -231,7 +233,8 @@ class AudioProcessor: "Audio uploads require ffmpeg and ffprobe to be installed on the server" ) from exc except subprocess.TimeoutExpired as exc: - raise ValidationException("Audio validation timed out") from exc + sentry_sdk.capture_exception(exc) + raise FileProcessingError("Audio validation timed out") from exc except (subprocess.CalledProcessError, ValueError) as exc: raise ValidationException("Uploaded audio is invalid or unreadable") from exc diff --git a/tests/utils/test_audio_processing.py b/tests/utils/test_audio_processing.py index 9ee46ce6..7884a184 100644 --- a/tests/utils/test_audio_processing.py +++ b/tests/utils/test_audio_processing.py @@ -67,14 +67,17 @@ def test_probe_audio_duration_timeout_raises_validation_exception(): processor = AudioProcessor() with ( + patch("src.utils.files.sentry_sdk.capture_exception") as mock_capture, patch( "src.utils.files.subprocess.run", side_effect=subprocess.TimeoutExpired(cmd="ffprobe", timeout=10), ), - pytest.raises(ValidationException, match="Audio validation timed out"), + pytest.raises(FileProcessingError, match="Audio validation timed out"), ): processor.probe_audio_duration_seconds_from_path(Path("/tmp/audio.mp3")) + mock_capture.assert_called_once() + @pytest.mark.asyncio async def test_audio_upload_requires_openai_client_before_processing(): @@ -203,6 +206,7 @@ async def test_audio_processor_extract_text_wraps_provider_errors(): request = httpx.Request("POST", "https://api.openai.com/v1/audio/transcriptions") with ( + patch("src.utils.files.sentry_sdk.capture_exception") as mock_capture, patch.object(processor, "_probe_audio_duration_seconds", return_value=1.0), patch( "src.utils.files.transcribe_audio", @@ -216,6 +220,8 @@ async def test_audio_processor_extract_text_wraps_provider_errors(): content_type="audio/mpeg", ) + mock_capture.assert_called_once() + @pytest.mark.asyncio async def test_audio_processor_extract_text_probes_in_background_thread():