diff --git a/src/log.d b/src/log.d index 849437f7..138276f4 100644 --- a/src/log.d +++ b/src/log.d @@ -21,6 +21,12 @@ void log(T...)(T args) logfileWriteLine(args); } +void fileOnly(T...)(T args) +{ + // Write to log file only + logfileWriteLine(args); +} + void vlog(T...)(T args) { if (verbose) { diff --git a/src/onedrive.d b/src/onedrive.d index a460165e..4eb35581 100644 --- a/src/onedrive.d +++ b/src/onedrive.d @@ -478,59 +478,62 @@ final class OneDriveApi switch(http.statusLine.code) { - - // case 1,2,3,4: - - // 200 - OK - // 201 - Created OK - // 202 - Accepted - // 204 - Deleted OK - case 200,201,202,204: - // No actions, but log if verbose logging - log.vlog("OneDrive Response: '", http.statusLine.code, " - ", http.statusLine.reason, "'"); - break; - - // 400 - Bad Request - case 400: - // Bad Request .. how should we act? - log.vlog("OneDrive returned a 'HTTP 400 - Bad Request' - gracefully handling error"); - break; - - // Item not found - case 404: - // Item was not found - do not throw an exception - log.vlog("OneDrive returned a 'HTTP 404 - Item not found' - gracefully handling error"); - break; - - // 409 - Conflict - case 409: - // Conflict handling .. how should we act? This only really gets triggered if we are using --local-first & we remove items.db as the DB thinks the file is not uploaded but it is - log.vlog("OneDrive returned a 'HTTP 409 - Conflict' - gracefully handling error"); - break; - - // 412 - Precondition Failed - case 412: - // A precondition provided in the request (such as an if-match header) does not match the resource's current state. - log.vlog("OneDrive returned a 'HTTP 412 - Precondition Failed' - gracefully handling error"); - break; - - // 415 - Unsupported Media Type - case 415: - // Unsupported Media Type ... sometimes triggered on image files, especially PNG - log.vlog("OneDrive returned a 'HTTP 415 - Unsupported Media Type' - gracefully handling error"); - break; - - // 500 - Internal Server Error - // 502 - Bad Gateway - // 503 - Service Unavailable - case 500,502,503: - // No actions - break; + // 200 - OK + case 200: + // No Log .. + break; + // 201 - Created OK + // 202 - Accepted + // 204 - Deleted OK + case 201,202,204: + // No actions, but log if verbose logging + log.vlog("OneDrive Response: '", http.statusLine.code, " - ", http.statusLine.reason, "'"); + break; + + // 400 - Bad Request + case 400: + // Bad Request .. how should we act? + log.vlog("OneDrive returned a 'HTTP 400 - Bad Request' - gracefully handling error"); + break; + + // Item not found + case 404: + // Item was not found - do not throw an exception + log.vlog("OneDrive returned a 'HTTP 404 - Item not found' - gracefully handling error"); + break; + + // 409 - Conflict + case 409: + // Conflict handling .. how should we act? This only really gets triggered if we are using --local-first & we remove items.db as the DB thinks the file is not uploaded but it is + log.vlog("OneDrive returned a 'HTTP 409 - Conflict' - gracefully handling error"); + break; + + // 412 - Precondition Failed + case 412: + // A precondition provided in the request (such as an if-match header) does not match the resource's current state. + log.vlog("OneDrive returned a 'HTTP 412 - Precondition Failed' - gracefully handling error"); + break; + + // 415 - Unsupported Media Type + case 415: + // Unsupported Media Type ... sometimes triggered on image files, especially PNG + log.vlog("OneDrive returned a 'HTTP 415 - Unsupported Media Type' - gracefully handling error"); + break; + + // Server side (OneDrive) Errors + // 500 - Internal Server Error + // 502 - Bad Gateway + // 503 - Service Unavailable + // 504 - Gateway Timeout (Issue #320) + case 500,502,503,504: + // No actions + log.vlog("OneDrive returned a 'HTTP 5xx Server Side Error' - gracefully handling error"); + break; - // "else" - default: - throw new OneDriveException(http.statusLine.code, http.statusLine.reason); - break; + // "else" + default: + throw new OneDriveException(http.statusLine.code, http.statusLine.reason); + break; } } diff --git a/src/sync.d b/src/sync.d index 2b44e0a8..d5260a16 100644 --- a/src/sync.d +++ b/src/sync.d @@ -404,8 +404,7 @@ final class SyncEngine private void applyDifference(JSONValue driveItem, string driveId, bool isRoot) { Item item = makeItem(driveItem); - //log.vlog("Processing item to apply differences"); - + if (isItemRoot(driveItem) || !item.parentId || isRoot) { item.parentId = null; // ensures that it has no parent item.driveId = driveId; // HACK: makeItem() cannot set the driveId propery of the root @@ -567,7 +566,7 @@ final class SyncEngine onedrive.downloadById(item.driveId, item.id, path); setTimes(path, item.mtime, item.mtime); writeln(" done."); - log.log("Downloading ", path, "... done."); + log.fileOnly("Downloading ", path, "... done."); } // returns true if the given item corresponds to the local one @@ -758,7 +757,7 @@ final class SyncEngine writeln(""); response = session.upload(path, item.driveId, item.parentId, baseName(path), eTag); } - log.log("Uploading file ", path, "... done."); + log.fileOnly("Uploading file ", path, "... done."); // saveItem(response); redundant // use the cTag instead of the eTag because Onedrive may update the metadata of files AFTER they have been uploaded eTag = response["cTag"].str; @@ -950,7 +949,9 @@ final class SyncEngine writeln(""); response = session.upload(path, parent.driveId, parent.id, baseName(path)); } - log.log("Uploading file ", path, "... done."); + log.fileOnly("Uploading file ", path, "... done."); + + // Update the item's metadata on OneDrive string id = response["id"].str; string cTag = response["cTag"].str; SysTime mtime = timeLastModified(path).toUTC(); @@ -979,7 +980,7 @@ final class SyncEngine writeln(""); response = session.upload(path, parent.driveId, parent.id, baseName(path)); } - log.log("Uploading file ", path, "... done."); + log.fileOnly("Uploading file ", path, "... done."); string id = response["id"].str; string cTag = response["cTag"].str; SysTime mtime = timeLastModified(path).toUTC(); @@ -1027,7 +1028,19 @@ final class SyncEngine "lastModifiedDateTime": mtime.toISOExtString() ]) ]; - auto response = onedrive.updateById(driveId, id, data, eTag); + + JSONValue response; + try { + response = onedrive.updateById(driveId, id, data, eTag); + } catch (OneDriveException e) { + if (e.httpStatusCode == 412) { + // OneDrive threw a 412 error, most likely: ETag does not match current item's value + // Retry without eTag + log.vlog("OneDrive returned a 'HTTP 412 - Precondition Failed' - gracefully handling error"); + string nullTag = null; + response = onedrive.updateById(driveId, id, data, nullTag); + } + } saveItem(response); }