Update handling of HTTP 412 - Precondition Failed errors (#issue 325) (#326)

* Update HTTP 412 - Precondition Failed messaging
* Add debug messaging when 5xx errors occur
* Update 5xx message to include
This commit is contained in:
abraunegg 2019-01-05 07:57:10 +11:00 committed by GitHub
parent bc059eaf0a
commit 388cc1ded5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 29 deletions

View file

@ -670,7 +670,7 @@ final class OneDriveApi
// 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");
log.vlog("OneDrive returned a 'HTTP ", http.statusLine.code, "Server Side Error' - gracefully handling error");
break;
// "else"
@ -695,7 +695,7 @@ final class OneDriveApi
// 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");
log.vlog("OneDrive returned a 'HTTP ", http.statusLine.code, "Server Side Error' - gracefully handling error");
break;
// Default - all other errors that are not a 2xx or a 302

View file

@ -64,6 +64,16 @@ private bool hasFileSize(const ref JSONValue item)
return ("size" in item) != null;
}
private bool hasId(const ref JSONValue item)
{
return ("id" in item) != null;
}
private bool hasName(const ref JSONValue item)
{
return ("name" in item) != null;
}
// construct an Item struct from a JSON driveItem
private Item makeItem(const ref JSONValue driveItem)
{
@ -309,6 +319,7 @@ final class SyncEngine
if (e.httpStatusCode >= 500) {
// OneDrive returned a 'HTTP 5xx Server Side Error' - gracefully handling error - error message already logged
log.vdebug("ERROR: OneDrive 'HTTP 5xx Server Side Error' when running applyDifferencesSingleDirectory()");
return;
}
}
@ -396,6 +407,7 @@ final class SyncEngine
if (e.httpStatusCode >= 500) {
// OneDrive returned a 'HTTP 5xx Server Side Error' - gracefully handling error - error message already logged
log.vdebug("ERROR: OneDrive 'HTTP 5xx Server Side Error' when running deleteDirectoryNoSync()");
return;
}
}
@ -428,6 +440,7 @@ final class SyncEngine
if (e.httpStatusCode >= 500) {
// OneDrive returned a 'HTTP 5xx Server Side Error' - gracefully handling error - error message already logged
log.vdebug("ERROR: OneDrive 'HTTP 5xx Server Side Error' when running renameDirectoryNoSync()");
return;
}
}
@ -460,6 +473,7 @@ final class SyncEngine
if (e.httpStatusCode >= 500) {
// OneDrive returned a 'HTTP 5xx Server Side Error' - gracefully handling error - error message already logged
log.vdebug("ERROR: OneDrive 'HTTP 5xx Server Side Error' when running applyDifferences()");
return;
}
}
@ -590,6 +604,7 @@ final class SyncEngine
if (e.httpStatusCode >= 500) {
// OneDrive returned a 'HTTP 5xx Server Side Error' - gracefully handling error - error message already logged
log.vdebug("ERROR: OneDrive 'HTTP 5xx Server Side Error' when running applyDifferences() - oneDriveMovedNotDeleted");
return;
}
}
@ -1107,7 +1122,8 @@ final class SyncEngine
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");
log.vlog("Simple Upload Replace Failed - OneDrive eTag / cTag match issue");
log.vlog("OneDrive returned a 'HTTP 412 - Precondition Failed' - gracefully handling error. Will upload as new file.");
itemdb.deleteById(item.driveId, item.id);
return;
}
@ -1128,7 +1144,8 @@ final class SyncEngine
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");
log.vlog("Session Upload Replace Failed - OneDrive eTag / cTag match issue");
log.vlog("OneDrive returned a 'HTTP 412 - Precondition Failed' - gracefully handling error. Will upload as new file.");
itemdb.deleteById(item.driveId, item.id);
return;
}
@ -1320,6 +1337,7 @@ final class SyncEngine
if (e.httpStatusCode >= 500) {
// OneDrive returned a 'HTTP 5xx Server Side Error' - gracefully handling error - error message already logged
log.vdebug("ERROR: OneDrive 'HTTP 5xx Server Side Error' when running uploadCreateDir()");
return;
}
}
@ -1365,34 +1383,43 @@ final class SyncEngine
if (e.httpStatusCode >= 500) {
// OneDrive returned a 'HTTP 5xx Server Side Error' - gracefully handling error - error message already logged
log.vdebug("ERROR: OneDrive 'HTTP 5xx Server Side Error' when running uploadCreateDir() - test if path exists");
return;
}
}
// https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file
// Do not assume case sensitivity. For example, consider the names OSCAR, Oscar, and oscar to be the same,
// even though some file systems (such as a POSIX-compliant file system) may consider them as different.
// Note that NTFS supports POSIX semantics for case sensitivity but this is not the default behavior.
if (response["name"].str == baseName(path)){
// OneDrive 'name' matches local path name
log.vlog("The requested directory to create was found on OneDrive - skipping creating the directory: ", path );
// Check that this path is in the database
if (!itemdb.selectById(parent.driveId, parent.id, parent)){
// parent for 'path' is NOT in the database
log.vlog("The parent for this path is not in the local database - need to add parent to local database");
string parentPath = dirName(path);
uploadCreateDir(parentPath);
// Ensure that the response has a name which we can check & validate
if (hasName(response)){
// https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file
// Do not assume case sensitivity. For example, consider the names OSCAR, Oscar, and oscar to be the same,
// even though some file systems (such as a POSIX-compliant file system) may consider them as different.
// Note that NTFS supports POSIX semantics for case sensitivity but this is not the default behavior.
if (response["name"].str == baseName(path)){
// OneDrive 'name' matches local path name
log.vlog("The requested directory to create was found on OneDrive - skipping creating the directory: ", path );
// Check that this path is in the database
if (!itemdb.selectById(parent.driveId, parent.id, parent)){
// parent for 'path' is NOT in the database
log.vlog("The parent for this path is not in the local database - need to add parent to local database");
string parentPath = dirName(path);
uploadCreateDir(parentPath);
} else {
// parent is in database
log.vlog("The parent for this path is in the local database - adding requested path (", path ,") to database");
auto res = onedrive.getPathDetails(path);
saveItem(res);
}
} else {
// parent is in database
log.vlog("The parent for this path is in the local database - adding requested path (", path ,") to database");
auto res = onedrive.getPathDetails(path);
saveItem(res);
// They are the "same" name wise but different in case sensitivity
log.error("ERROR: A local directory has the same name as another local directory.");
log.error("ERROR: To resolve, rename this local directory: ", absolutePath(path));
log.log("Skipping: ", absolutePath(path));
return;
}
} else {
// They are the "same" name wise but different in case sensitivity
log.error("ERROR: A local directory has the same name as another local directory.");
log.error("ERROR: To resolve, rename this local directory: ", absolutePath(path));
// response json is invalid
log.error("ERROR: Unable to process request due to an error with getting data from OneDrive");
log.log("Skipping: ", absolutePath(path));
return;
}
@ -1549,6 +1576,7 @@ final class SyncEngine
if (e.httpStatusCode >= 500) {
// OneDrive returned a 'HTTP 5xx Server Side Error' - gracefully handling error - error message already logged
log.vdebug("ERROR: OneDrive 'HTTP 5xx Server Side Error' when running uploadNewFile() - test if file exists");
return;
}
}
@ -1660,13 +1688,15 @@ final class SyncEngine
} 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");
log.vlog("OneDrive returned a 'HTTP 412 - Precondition Failed' when attempting file time stamp update - gracefully handling error");
string nullTag = null;
// Retry without eTag so we dont try and match against the etag / ctag
response = onedrive.updateById(driveId, id, data, nullTag);
}
}
saveItem(response);
}
if (hasId(response)) {
saveItem(response);
}
}
private void saveItem(JSONValue jsonItem)