GCS: Retry on 410 gone errors in BlobWriteChannel.flushBuffer - google-cloud-storage

We are using GCS to store blob files. We provide a GCS implementation of an interface provided by an internal library. The implementation returns a WritableByteChannel which is used by the library. This means, adding a retry logic is not an easy option for us. Looking at the stack trace below, we see that it is created in the BlobWriteChannel.flushBuffer method.
Is there any way for me to retry on such errors?
Caused by: com.google.cloud.storage.StorageException: 410 Gone
! {
! "error": {
! "errors": [
! {
! "domain": "global",
! "reason": "backendError",
! "message": "Backend Error"
! }
! ],
! "code": 500,
! "message": "Backend Error"
! }
! }
!
! at com.google.cloud.storage.spi.v1.HttpStorageRpc.translate(HttpStorageRpc.java:227)
! at com.google.cloud.storage.spi.v1.HttpStorageRpc.write(HttpStorageRpc.java:762)
! at com.google.cloud.storage.BlobWriteChannel$1.run(BlobWriteChannel.java:51)
! at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
! at com.google.api.gax.retrying.DirectRetryingExecutor.submit(DirectRetryingExecutor.java:105)
! at com.google.cloud.RetryHelper.run(RetryHelper.java:76)
! at com.google.cloud.RetryHelper.runWithRetries(RetryHelper.java:50)
! at com.google.cloud.storage.BlobWriteChannel.flushBuffer(BlobWriteChannel.java:44)
! at com.google.cloud.BaseWriteChannel.close(BaseWriteChannel.java:151)

This is the error 410 gone. And according to the GCP documentation, “410 gone” means you are trying to upload a file by reusing an invalid session. However, this error you observed seems a known issue, which was reported on this link. I recommend that you follow up on the link for updates and fixes.

For posterity, we've been seeing 410 GONE errors occasionally during big uploads or compose() calls. We are working with Google support about this. To quote:
As of right now, the issue is a bug and not a customer issue, and while a fix is on the way, there is a workaround that can be done on the customer’s side. The official workaround to circumvent 5xx and 410 errors is to implement retries, as was indicated in this comment from a Issue Tracker entry you have commented yourself (see this blog comment). The retry method recommendation can also be seen in this discussion.
To retry successfully, catching 500 and 410 errors is required and, as the official documentation recommends, implementing a retry by starting a new session for the upload that received an unsuccessful status code but still needs uploading. The new session creation may be what was missing on your end, causing retries to be unsuccessful as you have mentioned previously. Additionally, exponential backoffs recommended in comments are the way to go to mitigate the issue -- see the docs about that.

Related

What is the best HTTP status code error for failed password update?

I'm building some REST API to be used in a native iOS/Android app.
One of the endpoints allows the user to update his password by providing 2 fields: old_password and password.
Which HTTP status code should I in the situation where the old_password is incorrect?
My first thought was a 401 error but I already use it when the authentication token is invalid and it automatically triggers a logout in the app.
400 doesn't seem to fit because the request is actually semantically correct, it is a specific authentication error. Maybe 422?
One thing to keep in mind is that status codes, like response headers, are metadata; they are there so that generic components that know nothing about the details of your API can participate intelligently -- for example, by invalidating caches, or throwing up dialogs to collect authentication credentials.
400 doesn't seem to fit because the request is actually semantically correct
In practice, 400 is usually fine; clients are supposed to treat an unrecognized 4xx class status code as they would treat 400. Put another way, you can use 400 unless you specifically want to induce a different behavior by the generic components.
For your specific case, 409 Conflict is probably the closest match
The 409 (Conflict) status code indicates that the request could not be completed due to a conflict with the current state of the target resource. This code is used in situations where the user might be able to resolve the conflict and resubmit the request. The server SHOULD generate a payload that includes enough information for a user to recognize the source of the conflict.
RFC 5789 suggests a distinction between 409 and 422 that may be interesting. Paraphrasing this distinction
422: This might include attempts to modify a resource in a way that would cause the resource to become invalid
409: the request cannot be applied given the state of the resource.
You can also make a reasonable argument that the entire 4xx class of response codes is inappropriate. For example, if the request method is POST, then the server is expected to
process the representation enclosed in the request according to the resource's own specific semantics
Which it did; successfully, even. It just didn't produce the most commonly expected successful result.
On the other hand, the JSON Patch would argue the other direction; your attempt to change the password would probably look something like
[
{ "op": "test", "path": "/password", "value": "old_password" },
{ "op": "replace", "path": "/password", "value": "new_password" }
]
If you provided the wrong password in the test, then that operation would be considered unsuccessful, which would in turn mean that the PATCH is unsuccessful. That in turn would invoke the arguments for error handling as described in HTTP Patch.

How can I elminated warnings in Gatling ReponseProcessor

I have some code in my scenario such as
.check(status.is(200), jsonPath("$['resultData'][*]['#contentType']").findAll.saveAs("resultData"))
.check(status.is(500), jsonPath("$['processingError']").find.saveAs("processingError"))
but I keep getting the following
10:36:51.946 [WARN ] i.g.h.a.ResponseProcessor - Request 'GetAllThings' failed: status.find.is(200), but actually found 500
10:36:52.344 [WARN ] i.g.h.a.ResponseProcessor - Request 'GetAllThings' failed: status.find.is(500), but actually found 200
Is there some way I can construct my checks so that I don't get these messages, because I am already handling both cases?
I have tried several variations, but nothing seems to work.
Okay, this does what I want (mostly)
.check(
status.in(Seq(200, 400, 500)),
jsonPath("$['resultData'][*]").findAll.optional.saveAs("resultData"),
jsonPath("$['processingError']").optional.saveAs("processingError")
)
I say mostly because while it solves one problem, it creates another. Basically the 400 and 500 errors are captured, but now they are not marked as KO, so the statistics don't count them. I tried explicitly returning
sesson.markAsFailed
in my exec(), but that does not work, probably because once you are out of the check, the failure does not count (pun intended).

chrome.sockets API tcp error codes?

I'm developping a HTTP serveur as a Chrome App but I don't know how to interpret error codes caught in:
chrome.sockets.tcp.onReceiveError.addListener( (info) =>
console.error( "Error on Receive: socket=%s, resultCode=%s", info.socketId, info.resultCode )
)
Sometimes I get the following error with info.resultCode = -100 (when the connection is timed out).
I've found some Unix/Sockets codes but they don't seem to match, and I found nothing on Google's Chrome App Dev website.
This one and this one could match but I'm not sure.
For example, with that commented error list, I can guess the error 10064 is corresponding to my -100 resultCode.
Can someone direct me to the right documentation?
It looks like there is a list of them defined in net_error_list.h

Facebook graph api limit parameter strange behaviour

Until today I could do requests such as the following successfully
https://graph.facebook.com/v2.2/[PAGE_ID]/posts?access_token=[TOKEN]&since=2014-03-17T00:00:00Z&until=2014-03-17T23:59:59Z&limit=250&fields=id,message
Today when I tried to make this request I get the following response:
{
"error":{
"message":"(#100) The 'limit' parameter should not exceed 200",
"type":"OAuthException","code":100
}
}
Which is funny because the graph api mentions that the upper bound of the limit parameter is 250. Am I missing something or is there something wrong with the API?
This bug as been corrected as of January 30th.
Post limit change from documented max of 250 to 200 bug report
#Potaoes I suspect this is an error related to them solving some back-end and latency issues. Discussed here. https://developers.facebook.com/status/issues/320942614776706/
They are currently in the middle of push ( I assume to correct this error). https://developers.facebook.com/status/dashboard/
Finally the error has been reported. https://developers.facebook.com/bugs/1518130385135066/
#Vineesh The OP is correct. It's against all the API documentation that the limit has been 250 since v2.0. There has been no documented change to this.
The Error message exactly shows the Error.
The 'limit' parameter should not exceed 200",
You have given limit=250,
reduce the limit then try again.

Paypal API : Mass Pay uncomprehensible error

I'm trying to get MassPay working on my website. Here's my code:
http://pastebin.com/rNGzXrq0
But it's uncomprehensible, as it gives me the error response "the number of input records is less than or equal to zero" even If there is 2 input records in the request.
How can I solve this ?
Thank you for your help :)
I noticed you have
'L_ATM0' => '5.00',
It should be
'L_AMT0' => '5.00',
The full list of PayPal API error messages can be found here.
The "long message" that you're receiving from the API is very poorly worded to the point of being almost useless.
Thankfully, the "short message" is a lot more helpful:
Transaction refused because of an invalid argument. See additional error messages for details.
So the error in question is related to a bad argument being passed.