Repository: qdrant/qdrant
File: src/actix/api/snapshot_api.rs (Rust)

Code before:
    };

    let future = cancel::future::spawn_cancel_on_drop(async move |cancel| {
        let _recovery_lock = recovery_lock;
        let download_start_time = tokio::time::Instant::now();

        let cancel_safe = async {
            let toc = dispatcher.toc(&access, &pass);

            let collection_pass = access
                .check_global_access(AccessRequirements::new().manage())?
                .issue_pass(&collection_name)
                .into_static();

            let collection = toc.get_collection(&collection_pass).await?;
            collection.assert_shard_exists(shard_id).await?;

            let http_client = http_client.client(api_key.as_deref())?;

            let encoded_collection_name = urlencoding::encode(&collection_name);
            let create_snapshot_url = format!(
                "{peer_url}/collections/{encoded_collection_name}/shards/{shard_id}/snapshot/partial/create"
            );

            // Empty snapshot manifest allows us to use partial snapshots even if local shard doesn't exist
            let snapshot_manifest = collection.get_partial_snapshot_manifest(shard_id).await.unwrap_or_else(|_| SnapshotManifest::empty());

            let download_dir = toc.optional_temp_or_snapshot_temp_path()?;
            let (partial_snapshot_file, partial_snapshot_temp_path) = tempfile::Builder::new()
                .prefix("partial-snapshot")
                .suffix(".download")
                .tempfile_in(&download_dir)?
                .into_parts();
            let partial_snapshot_file = fs::File::from_parts::<&Path>(
                partial_snapshot_file,
                partial_snapshot_temp_path.as_ref(),
            );

            let response = http_client
                .post(create_snapshot_url)
                .json(&snapshot_manifest)
                .send()
                .await?
                .error_for_status()?;

            if response.status() == reqwest::StatusCode::NOT_MODIFIED {
                let shard_holder = collection.shards_holder();
                let shard_holder = shard_holder.read().await;
                let replica_set = shard_holder
                    .get_shard(shard_id)
                    .ok_or_else(|| shard_not_found_error(shard_id))?;

Review comment (bug):
There might be different error types, it's incorrect to ignore _all_ errors and unwrap into empty manifest.

Code after:
        }
    };

    let future = cancel::future::spawn_cancel_on_drop(async move |cancel| {
        let _recovery_lock = recovery_lock;
        let download_start_time = tokio::time::Instant::now();

        let cancel_safe = async {
            let toc = dispatcher.toc(&access, &pass);

            let collection_pass = access
                .check_global_access(AccessRequirements::new().manage())?
                .issue_pass(&collection_name)
                .into_static();

            let collection = toc.get_collection(&collection_pass).await?;
            collection.assert_shard_exists(shard_id).await?;

            let http_client = http_client.client(api_key.as_deref())?;

            let encoded_collection_name = urlencoding::encode(&collection_name);
            let create_snapshot_url = format!(
                "{peer_url}/collections/{encoded_collection_name}/shards/{shard_id}/snapshot/partial/create"
            );

            // Empty snapshot manifest allows us to use partial snapshots even if local shard doesn't exist
            let snapshot_manifest = match collection.get_partial_snapshot_manifest(shard_id).await {
                Ok(manifest) => manifest,
                Err(CollectionError::NotFound { .. }) => SnapshotManifest::default(),
                Err(err) => return Err(StorageError::from(err))
            };

            let download_dir = toc.optional_temp_or_snapshot_temp_path()?;
            let (partial_snapshot_file, partial_snapshot_temp_path) = tempfile::Builder::new()
                .prefix("partial-snapshot")
                .suffix(".download")
                .tempfile_in(&download_dir)?
                .into_parts();
            let partial_snapshot_file = fs::File::from_parts::<&Path>(
                partial_snapshot_file,
                partial_snapshot_temp_path.as_ref(),
            );

            let response = http_client
                .post(create_snapshot_url)
                .json(&snapshot_manifest)
                .send()
                .await?
                .error_for_status()?;

            if response.status() == reqwest::StatusCode::NOT_MODIFIED {