Hello,
In transitioning my API 1 Obj-C code over to API 2, I'm slightly confused over how to deal with certain error codes in API 2 - or even how to locate them properly.
# 1. Create Folder Errors
When creating a folder in API 1, if something went wrong, the delegate's -restClient:createFolderFailedWithError: method would be called. I could then check the (NS)error code. For example, I could check (error.code == 403) to see if the method failed because the folder already existed. In that case, I wouldn't have to cancel all following operations, since such an error may not be fatal.
How do I do this in API 2? API 1's endpoint reference lists specific codes for each API call (such as the 403 for "folder already exists" for the create_folder API call). API 2 has no such specific codes, but only some generic codes--always using 409 for anything endpoint-specific, telling you instead to check the JSON response body.
So, in the Obj-C frameworks, how do I detect from the JSON response body that -createFolder: failed specifically because a folder already exists at that path? From hunting through the header files, the closest I can find is to do something like this:
DBFILESCreateFolderError *folderError; // From the result callback.
BOOL folderExists = (folderError.isPath && folderError.path.isConflict);
(Obviously this does not specifically check that there is a folder already at the path, just that there is a conflict.)
Is there a better way?
# 2. Delete Files Errors
Likewise, with "delete file", API 1 returned a 404 error if the file did not exist on the server - another error that I could ignore since I was trying to delete a nonexistent file. How do I check for this case using the API 2 Obj-C frameworks?
# 3. Rate Limit Errors
I can see that there is a specific object for rate limit errors (DBAuthRateLimitError) which allows you to get the rety-after value. Great! I had to swizzle in my own replacement method to get this information in API 1. So now all I have to do to get the retry-after value is this, I believe:
DBError *error; // Received in result block.
if (error.statusCode == 429)
{
NSInteger retryAfter = error.structuredRateLimitError.retryAfter.integerValue;
// Try again after retryAfter...
}
That's great! I'm glad this is included. However:
- What is the difference between error.backoff and error.structuredRateLimitError.retryAfter.integerValue?
From searching the .m files, I *think* these are the same. So presumably I only need to check error.backoff to determine how long to wait before trying again after a 429 error, and do not need to worry about the structuredRateLimitError.retryAfter value?
# 4. Reading Error Codes
What is the best way of checking an error code in general? Is it to call -statusCode on the DBError object or -code on the DBError's nsError property object? It seems that -nsError can sometimes be nil, so I cannot rely on generalError.nsError.code. Is the -statusCode of DBError always the one to check? And is it always identical to the nsError code when nsError is not nil? I use the NSError domain and code to check for a number of generic HTTP errors as defined in the Apple NSError docs, for instance.
# 5. Checking for Over Quota Error
API 1 lists 507 as the specific error to check to see if a user is over his or her Dropbox quota. No such error code is listed for API 2. Can I still check for this error code (using generalError.statusCode?), or is it no longer used? If not, how can I check for this failure case so that I can communicate to the user that he or she needs to upgrade or tidy up their Dropbox account in order to continue syncing?
Apologies for another long post...
Thanks!
Keith