@@ -65,20 +65,26 @@ async def extract_text(self, file_id: UUID, job_id: str):
6565 CancelledError: If the job is cancelled
6666 Exception: For any extraction or upload errors
6767 """
68- error_log = []
69- async with self ._uow () as uow :
70- extraction = await uow .files .get_extraction_by_file_id (file_id = file_id )
71- file = await uow .files .get (file_id = file_id )
72- error_log .append (file .model_dump ())
73- user = await uow .users .get (user_id = file .created_by )
74-
75- extraction .set_started (
76- job_id = job_id ,
77- backend = self ._extraction_backend .backend_name ,
78- )
79- await uow .files .update_extraction (extraction = extraction )
80- await uow .commit ()
68+ error_log : list [str ] = []
69+ extraction : TextExtraction | None = None
70+ file : File | None = None
71+ user : User | None = None
72+ uploaded_file_ids : list [UUID ] = []
73+
8174 try :
75+ async with self ._uow () as uow :
76+ extraction = await uow .files .get_extraction_by_file_id (file_id = file_id )
77+ file = await uow .files .get (file_id = file_id )
78+ error_log .append (file .model_dump ())
79+ user = await uow .users .get (user_id = file .created_by )
80+
81+ extraction .set_started (
82+ job_id = job_id ,
83+ backend = self ._extraction_backend .backend_name ,
84+ )
85+ await uow .files .update_extraction (extraction = extraction )
86+ await uow .commit ()
87+
8288 file_url = await self ._object_storage .get_file_url (file_id = file_id )
8389 error_log .append (f"file url: { file_url } " )
8490
@@ -95,24 +101,30 @@ async def extract_text(self, file_id: UUID, job_id: str):
95101 context_id = file .context_id ,
96102 parent_file_id = file_id ,
97103 )
104+ uploaded_file_ids .append (extracted_db_file .id )
98105 extracted_files .append (ExtractedFileInfo (file_id = extracted_db_file .id , format = extraction_format ))
99106
100107 extraction .set_completed (extracted_files = extracted_files )
101108 async with self ._uow () as uow :
102109 await uow .files .update_extraction (extraction = extraction )
103110 await uow .commit ()
111+ uploaded_file_ids .clear ()
104112 except CancelledError :
105- async with self ._uow () as uow :
106- extraction .set_cancelled ()
107- await uow .files .update_extraction (extraction = extraction )
108- await uow .commit ()
113+ await self ._cleanup_extracted_files (uploaded_file_ids )
114+ if extraction :
115+ async with self ._uow () as uow :
116+ extraction .set_cancelled ()
117+ await uow .files .update_extraction (extraction = extraction )
118+ await uow .commit ()
109119 raise
110120 except Exception as ex :
111121 error_log .append (str (ex ))
112- async with self ._uow () as uow :
113- extraction .set_failed ("\n " .join (str (e ) for e in error_log ))
114- await uow .files .update_extraction (extraction = extraction )
115- await uow .commit ()
122+ await self ._cleanup_extracted_files (uploaded_file_ids )
123+ if extraction :
124+ async with self ._uow () as uow :
125+ extraction .set_failed ("\n " .join (str (e ) for e in error_log ))
126+ await uow .files .update_extraction (extraction = extraction )
127+ await uow .commit ()
116128 raise
117129
118130 async def upload_file (
@@ -202,6 +214,22 @@ async def delete(self, *, file_id: UUID, user: User, context_id: UUID | None = N
202214 await self ._object_storage .delete_files (file_ids = file_ids_to_delete )
203215 await uow .commit ()
204216
217+ async def _cleanup_extracted_files (self , file_ids : list [UUID ]) -> None :
218+ """Best-effort cleanup for partially uploaded extracted files."""
219+ if not file_ids :
220+ return
221+
222+ unique_ids = list (dict .fromkeys (file_ids ))
223+
224+ with suppress (Exception ):
225+ await self ._object_storage .delete_files (file_ids = unique_ids )
226+
227+ with suppress (Exception ):
228+ async with self ._uow () as uow :
229+ for extracted_file_id in unique_ids :
230+ await uow .files .delete (file_id = extracted_file_id )
231+ await uow .commit ()
232+
205233 async def create_extraction (
206234 self ,
207235 * ,
0 commit comments