1
votes

My app updates gmail drafts on an interval using the gmail api. I'm finding that if I happen to overlap gmail api update calls for the same draft id (which can be quite easy to do since the API sometimes takes 10sec to respond), the API will completely corrupt the draft such that I get a "Backend Error" every time I try to access it again.

Here are calls to repro:

  1. Create a draft:

    curl https://www.googleapis.com/gmail/v1/users/me/drafts -H "Authorization: Bearer redacted" -H "Content-Type: application/json" -d '{ "message": { "raw": "RnJvbTogJ21lJw0KVG86IGJyYWRAbWl4bWF4LmNvbQ0KU3ViamVjdDogVGVzdCBEcmFmdCENCkNvbnRlbnQtVHlwZTogdGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04DQoNCk15IG1lc3NhZ2U=" } }' { "id": "r7481949043481090326", "message": { "id": "14c53392c1ad1a38", "threadId": "14c53392c1ad1a38", "labelIds": [ "DRAFT" ] } }

  2. Update that draft twice at the same time (notice commands are run in parallel):

    curl -X PUT https://www.googleapis.com/gmail/v1/users/me/drafts/r7481949043481090326 -H "Authorization: Bearer redacted" -H "Content-Type: application/json" -d '{ "message": { "raw": "RnJvbTogJ21lJw0KVG86IGJyYWRAbWl4bWF4LmNvbQ0KU3ViamVjdDogVGVzdCBEcmFmdCENCkNvbnRlbnQtVHlwZTogdGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04DQoNCk15IG1lc3NhZ2U=" } }' & curl -X PUT https://www.googleapis.com/gmail/v1/users/me/drafts/r7481949043481090326 -H "Authorization: Bearer redacted" -H "Content-Type: application/json" -d '{ "message": { "raw": "RnJvbTogJ21lJw0KVG86IGJyYWRAbWl4bWF4LmNvbQ0KU3ViamVjdDogVGVzdCBEcmFmdCENCkNvbnRlbnQtVHlwZTogdGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04DQoNCk15IG1lc3NhZ2U=" } }' [1] 96019 { "id": "r7481949043481090326", "message": { "id": "14c5339e1cbcb58b", "threadId": "14c5339e1cbcb58b", "labelIds": [ "DRAFT" ] } } { "error": { "errors": [ { "domain": "global", "reason": "backendError", "message": "Backend Error" } ], "code": 500, "message": "Backend Error" } }

Notice the "Backend Error" for the second call. Now there will be two drafts in the user's drafts folder in gmail.

  1. Now, after both update calls are finished, try to GET the draft:

    curl https://www.googleapis.com/gmail/v1/users/me/drafts/r7481949043481090326 -H "Authorization: Bearer redacted" { "error": { "errors": [ { "domain": "global", "reason": "backendError", "message": "Backend Error" } ], "code": 500, "message": "Backend Error" } }

All subsequent calls to get or update the draft by that ID will return Backend Error, and the user is also left with two copies in their draft folder.

The obvious workaround is just to add protections such that I never try to update the same draft id concurrently. But this is a pretty serious bug that should be looked at by the Gmail team.

1
FYI, there's a link to "Issue Tracker" in the Gmail API docs: developers.google.com/gmail/api (left-hand nav under "Support") For things that are clearly bugs you're welcome to just report them there.Eric D
Eric, thanks! I didn't even see the issue tracker. Filed there: code.google.com/a/google.com/p/apps-api-issues/issues/…Brad Vogel
did you get final solution or bug ?Kiquenet
Yes, bug here: code.google.com/a/google.com/p/apps-api-issues/issues/…. My solution is to just use locking to make sure draft update calls never overlap.Brad Vogel

1 Answers