diff --git a/myproject/products/models/photos.py b/myproject/products/models/photos.py index 15aed86..ef1e3fd 100644 --- a/myproject/products/models/photos.py +++ b/myproject/products/models/photos.py @@ -102,7 +102,8 @@ class BasePhoto(models.Model): photo_id=self.pk, photo_model=photo_model_class, status='pending', - task_id=task_result.id + task_id=task_result.id, + result_data={'temp_path': getattr(temp_image, 'name', None)} ) except ImportError: diff --git a/myproject/products/tasks.py b/myproject/products/tasks.py index 0ecb113..45718fa 100644 --- a/myproject/products/tasks.py +++ b/myproject/products/tasks.py @@ -101,9 +101,26 @@ def process_product_photo_async(self, photo_id, photo_model_class, schema_name): } } - except PhotoModel.DoesNotExist: + except PhotoModel.DoesNotExist as e: logger.error(f"[Celery] Photo {photo_id} not found in schema {schema_name}") - return {'status': 'error', 'reason': 'not_found', 'photo_id': photo_id} + # Retry briefly to allow DB transaction to commit (race condition on first photo) + try: + raise self.retry(exc=e, countdown=5) + except self.MaxRetriesExceededError: + # Final failure: attempt to delete the orphan temp file if we recorded it + try: + from .models.photos import PhotoProcessingStatus + status = (PhotoProcessingStatus.objects + .filter(photo_id=photo_id, photo_model=photo_model_class) + .order_by('-created_at') + .first()) + temp_path = (status.result_data or {}).get('temp_path') if status else None + if temp_path and default_storage.exists(temp_path): + default_storage.delete(temp_path) + logger.info(f"[Celery] Deleted temp file (not_found): {temp_path}") + except Exception as del_exc: + logger.warning(f"[Celery] Could not delete temp file for photo {photo_id} on not_found: {del_exc}") + return {'status': 'error', 'reason': 'not_found', 'photo_id': photo_id} except Exception as exc: logger.error(f"[Celery] Error processing photo {photo_id} in {schema_name}: {str(exc)}",