Resolve file / folder upload issues (Issue #598) (#602)

* Without this throw, uploadLastModifiedTime fails to catch that the 412 error was returned, thus, the retry with a null cTag / eTag is not performed which leads to 'OneDrive response missing required 'id' element' being generated.
* Fix 'Unexpected character '<'. (Line 1:1)' when OneDrive has an exception error
* Validate that the response from OneDrive is a valid JSON object
This commit is contained in:
abraunegg 2019-07-27 05:24:59 +10:00 committed by GitHub
parent f111eab71a
commit 3171318503
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 35 additions and 26 deletions

View file

@ -627,9 +627,8 @@ final class OneDriveApi
try { try {
json = content.parseJSON(); json = content.parseJSON();
} catch (JSONException e) { } catch (JSONException e) {
e.msg ~= "\n"; // Log that a JSON Exception was caught, dont output the HTML response from OneDrive
e.msg ~= content; log.vdebug("JSON Exception caught when performing HTTP operations - use --debug-https to diagnose further");
throw e;
} }
return json; return json;
} }
@ -780,7 +779,8 @@ final class OneDriveApi
// 412 - Precondition Failed // 412 - Precondition Failed
case 412: case 412:
log.vlog("OneDrive returned a 'HTTP 412 - Precondition Failed' - gracefully handling error"); log.vlog("OneDrive returned a 'HTTP 412 - Precondition Failed' - gracefully handling error");
break; // Throw this as a specific exception so this is caught when performing uploadLastModifiedTime
throw new OneDriveException(http.statusLine.code, http.statusLine.reason, response);
// Server side (OneDrive) Errors // Server side (OneDrive) Errors
// 500 - Internal Server Error // 500 - Internal Server Error

View file

@ -1921,7 +1921,7 @@ final class SyncEngine
string parentPath = dirName(path); // will be either . or something else string parentPath = dirName(path); // will be either . or something else
try { try {
log.vdebug("Attempting to query OneDrive for this path: ", parentPath); log.vdebug("Attempting to query OneDrive for this parent path: ", parentPath);
onedrivePathDetails = onedrive.getPathDetails(parentPath); onedrivePathDetails = onedrive.getPathDetails(parentPath);
} catch (OneDriveException e) { } catch (OneDriveException e) {
// exception - set onedriveParentRootDetails to a blank valid JSON // exception - set onedriveParentRootDetails to a blank valid JSON
@ -2001,30 +2001,39 @@ final class SyncEngine
} }
} }
// https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file // response from OneDrive has to be a valid JSON object
// Do not assume case sensitivity. For example, consider the names OSCAR, Oscar, and oscar to be the same, if (response.type() == JSONType.object){
// even though some file systems (such as a POSIX-compliant file system) may consider them as different. // https://docs.microsoft.com/en-us/windows/desktop/FileIO/naming-a-file
// Note that NTFS supports POSIX semantics for case sensitivity but this is not the default behavior. // 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)){ if (response["name"].str == baseName(path)){
// OneDrive 'name' matches local path name // OneDrive 'name' matches local path name
log.vlog("The requested directory to create was found on OneDrive - skipping creating the directory: ", path ); log.vlog("The requested directory to create was found on OneDrive - skipping creating the directory: ", path );
// Check that this path is in the database // Check that this path is in the database
if (!itemdb.selectById(parent.driveId, parent.id, parent)){ if (!itemdb.selectById(parent.driveId, parent.id, parent)){
// parent for 'path' is NOT in the database // 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"); log.vlog("The parent for this path is not in the local database - need to add parent to local database");
string parentPath = dirName(path); string parentPath = dirName(path);
uploadCreateDir(parentPath); 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 { } else {
// parent is in database // They are the "same" name wise but different in case sensitivity
log.vlog("The parent for this path is in the local database - adding requested path (", path ,") to database"); log.error("ERROR: Current directory has a 'case-insensitive match' to an existing directory on OneDrive");
auto res = onedrive.getPathDetails(path); log.error("ERROR: To resolve, rename this local directory: ", absolutePath(path));
saveItem(res); log.log("Skipping: ", absolutePath(path));
return;
} }
} else { } else {
// They are the "same" name wise but different in case sensitivity // response is not valid JSON, an error was returned from OneDrive
log.error("ERROR: Current directory has a 'case-insensitive match' to an existing directory on OneDrive"); log.error("ERROR: There was an error performing this operation on OneDrive");
log.error("ERROR: To resolve, rename this local directory: ", absolutePath(path)); log.error("ERROR: Increase logging verbosity to assist determining why.");
log.log("Skipping: ", absolutePath(path)); log.log("Skipping: ", absolutePath(path));
return; return;
} }