From 86ea576144ffd4bc2e02ab564fa0b761c8141918 Mon Sep 17 00:00:00 2001 From: abraunegg Date: Sun, 11 Nov 2018 11:15:48 +1100 Subject: [PATCH] Handle HTTP request returned status code 412 (Precondition Failed) for session uploads (#227) * Handle HTTP request returned status code 412 (Precondition Failed) for session uploads to OneDrive Personal Accounts * Fix Failed to remove file /root/.config/onedrive/resume_upload: No such file or directory if there is a session upload error and the resume file does not get created * Handle response codes when using 2 different systems using --upload-only but the same OneDrive account and uploading the same filename to the same location --- src/sync.d | 28 +++++++++++++++++++++++----- src/upload.d | 16 ++++++++++++---- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/src/sync.d b/src/sync.d index 3aff8940..4ea543da 100644 --- a/src/sync.d +++ b/src/sync.d @@ -977,6 +977,14 @@ final class SyncEngine try { response = onedrive.simpleUploadReplace(path, item.driveId, item.id, item.eTag); } catch (OneDriveException e) { + if (e.httpStatusCode == 404) { + // HTTP request returned status code 404 - the eTag provided does not exist + // Delete record from the local database - file will be uploaded as a new file + log.vlog("OneDrive returned a 'HTTP 404 - eTag Issue' - gracefully handling error"); + itemdb.deleteById(item.driveId, item.id); + return; + } + // Resolve https://github.com/abraunegg/onedrive/issues/36 if ((e.httpStatusCode == 409) || (e.httpStatusCode == 423)) { // The file is currently checked out or locked for editing by another user @@ -990,10 +998,10 @@ final class SyncEngine if (e.httpStatusCode == 412) { // HTTP request returned status code 412 - ETag does not match current item's value - // Remove the offending file from OneDrive - file will be uploaded as a new file - onedrive.deleteById(item.driveId, item.id, item.eTag); - // Delete from the local database + // Delete record from the local database - file will be uploaded as a new file + log.vlog("OneDrive returned a 'HTTP 412 - Precondition Failed' - gracefully handling error"); itemdb.deleteById(item.driveId, item.id); + return; } if (e.httpStatusCode == 504) { @@ -1006,7 +1014,17 @@ final class SyncEngine writeln("done."); } else { writeln(""); - response = session.upload(path, item.driveId, item.parentId, baseName(path), item.eTag); + try { + response = session.upload(path, item.driveId, item.parentId, baseName(path), item.eTag); + } catch (OneDriveException e) { + if (e.httpStatusCode == 412) { + // HTTP request returned status code 412 - ETag does not match current item's value + // Delete record from the local database - file will be uploaded as a new file + log.vlog("OneDrive returned a 'HTTP 412 - Precondition Failed' - gracefully handling error"); + itemdb.deleteById(item.driveId, item.id); + return; + } + } writeln("done."); } } else { @@ -1034,7 +1052,7 @@ final class SyncEngine saveItem(response); } log.fileOnly("Uploading file ", path, " ... done."); - // use the cTag instead of the eTag because OneDrive may update the metadata of files AFTER they have been uploaded + // use the cTag instead of the eTag because OneDrive may update the metadata of files AFTER they have been uploaded via simple upload eTag = response["cTag"].str; } if (accountType == "personal"){ diff --git a/src/upload.d b/src/upload.d index ddbc87d2..cd5d63b6 100644 --- a/src/upload.d +++ b/src/upload.d @@ -92,13 +92,17 @@ struct UploadSession } else { // unable to read the local file log.vlog("Restore file upload session failed - unable to read the local file"); - remove(sessionFilePath); + if (exists(sessionFilePath)) { + remove(sessionFilePath); + } return false; } } else { // session file contains an error - cant resume log.vlog("Restore file upload session failed - cleaning up session resume"); - remove(sessionFilePath); + if (exists(sessionFilePath)) { + remove(sessionFilePath); + } return false; } } @@ -136,14 +140,18 @@ struct UploadSession save(); } catch (OneDriveException e) { // there was an error remove session file - remove(sessionFilePath); + if (exists(sessionFilePath)) { + remove(sessionFilePath); + } return response; } } // upload complete p.next(); writeln(); - remove(sessionFilePath); + if (exists(sessionFilePath)) { + remove(sessionFilePath); + } return response; }