Skip to content

Commit 1c393b8

Browse files
committed
fix(services/onedrive): copy requires the destination items don't exist
1 parent 742f1ce commit 1c393b8

File tree

1 file changed

+24
-6
lines changed

1 file changed

+24
-6
lines changed

core/src/services/onedrive/core.rs

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,9 @@ impl OneDriveCore {
426426
self.info.http_client().send(request).await
427427
}
428428

429+
/// Delete a `DriveItem`
430+
///
431+
/// This moves the items to the recycle bin.
429432
pub(crate) async fn onedrive_delete(&self, path: &str) -> Result<Response<Buffer>> {
430433
let url = self.onedrive_item_url(path, true);
431434

@@ -451,7 +454,7 @@ impl OneDriveCore {
451454
return Err(parse_error(response));
452455
}
453456

454-
// We need to stat the parent folder to get a parent reference
457+
// We need to stat the destination parent folder to get a parent reference
455458
let destination_parent = get_parent(destination).to_string();
456459
let basename = get_basename(destination);
457460

@@ -464,11 +467,26 @@ impl OneDriveCore {
464467
},
465468
name: basename.to_string(),
466469
};
467-
let url: String = format!(
468-
"{}:/copy?@microsoft.graph.conflictBehavior={}",
469-
self.onedrive_item_url(source, true),
470-
REPLACE_EXISTING_ITEM_WHEN_CONFLICT
471-
);
470+
471+
// ensure the destination file or folder doesn't exist
472+
let response = self.onedrive_get_stat_plain(destination).await?;
473+
match response.status() {
474+
// We must remove the file or folder because
475+
// OneDrive doesn't support `conflictBehavior` for the consumer OneDrive.
476+
// `conflictBehavior` seems to work for the consumer OneDrive sometimes could be a coincidence.
477+
// Read more at https://learn.microsoft.com/en-us/graph/api/driveitem-copy
478+
StatusCode::OK => {
479+
let response = self.onedrive_delete(destination).await?;
480+
match response.status() {
481+
StatusCode::NO_CONTENT | StatusCode::NOT_FOUND => {} // expected, intentionally empty
482+
_ => return Err(parse_error(response)),
483+
}
484+
}
485+
StatusCode::NOT_FOUND => {} // expected, intentionally empty
486+
_ => return Err(parse_error(response)),
487+
}
488+
489+
let url: String = format!("{}:/copy", self.onedrive_item_url(source, true));
472490

473491
let body_bytes = serde_json::to_vec(&body).map_err(new_json_serialize_error)?;
474492
let buffer = Buffer::from(Bytes::from(body_bytes));

0 commit comments

Comments
 (0)