Closed Bug 1010531 Opened 11 years ago Closed 11 years ago

Sync spinning callback error path throws in two places, causing unhandled promise rejections and potential terror

Categories

(Cloud Services :: Firefox: Common, defect)

defect
Not set
normal
Points:
2

Tracking

(Not tracked)

VERIFIED FIXED
mozilla32
Iteration:
33.3

People

(Reporter: Yoric, Assigned: markh)

References

Details

(Whiteboard: [qa!])

Attachments

(1 file, 2 obsolete files)

This is one of the last few blockers for bug 976205. Unfortunately, I seems that I don't understand the code of Sync/FxA sufficiently to fix this.
Flags: needinfo?(ttaubert)
Flags: needinfo?(mhammond)
Marco, can you please add this to the current iteration?
Assignee: nobody → mhammond
Flags: needinfo?(ttaubert)
Flags: needinfo?(mmucci)
Flags: needinfo?(mhammond)
Flags: firefox-backlog+
Whiteboard: p=2
This seems to be caused by an unexpected (to me) implementation of makeSpinningCallback() - hence asking rnewman for review as he has the best understanding of those semantics. consider this code: let cb = Async.makeSpinningCallback(); somePromise().then(..., err => {cb(null, err)}; cb.wait(); I've always understood that the cb.wait() will throw - that's kind-of the point. What I *didn't* understand is that the cb(null, err) call *also* itself throws the very exception being passed in. Richard, assuming I'm not missing something, then this patch simply catches and ignores the error doing the cb(null, err), which would be the right thing to do. Or I am missing something and this patch would not be correct :) With this patch the tests all still pass without logging the promise rejection message. (FTR, the specific test failing is test_fxa_service_cluster.js)
Attachment #8422858 - Flags: review?(rnewman)
Thanks for the update Mark. Bug has been added to the iteration.
Status: NEW → ASSIGNED
Flags: needinfo?(mmucci)
Whiteboard: p=2 → p=2 s=it-32c-31a-30b.2 [qa?]
Note that these tests show up as EXPECTED-FAIL at the moment. The will show as UNEXPECTED-FAIL once bug 976205 lands.
Comment on attachment 8422858 [details] [diff] [review] 0002-Bug-1010531-avoid-unhandled-promise-rejection-fetchi.patch Review of attachment 8422858 [details] [diff] [review]: ----------------------------------------------------------------- ::: services/sync/modules/browserid_identity.js @@ +673,5 @@ > } else { > // callback with an error - cb.wait() completes by raising an exception. > + // BUT - it *also* causes cb(err) to throw the same exception! This > + // causes this promise chain to see an unhandled rejection - so mute > + // this exception (cb.wait() still throws though) Nit: I'd put that comment in the `catch` clause.
Whiteboard: p=2 s=it-32c-31a-30b.2 [qa?] → p=2 s=it-32c-31a-30b.2 [qa-]
Comment on attachment 8422858 [details] [diff] [review] 0002-Bug-1010531-avoid-unhandled-promise-rejection-fetchi.patch Review of attachment 8422858 [details] [diff] [review]: ----------------------------------------------------------------- I wonder if this is simply an error? E.g., we have storage callbacks like handleError: function handleError(error) { this.syncCb.throw(error); }, and I'd be surprised if every single internal invoker of callback APIs will correctly handle errors in callbacks. I'd be inclined to try removing that caller-throw, leaving only the one in waitForSyncCallback, and see if anything breaks... Clearing review pending that investigation.
Attachment #8422858 - Flags: review?(rnewman)
There were a couple of obvious places where the code assumed the current behaviour. These were relatively easy to fix, but it leaves me worries I missed a couple that aren't covered by unit tests. OTOH, a grep for ".throw" didn't show any. ISTM this fix is potentially more risky, but YMMV.
Attachment #8425143 - Flags: feedback?(rnewman)
Comment on attachment 8425143 [details] [diff] [review] 0001-Prevent-async-callback-from-throwing-when-a-callback.patch Review of attachment 8425143 [details] [diff] [review]: ----------------------------------------------------------------- It worries me that this doesn't cause any test failures. ::: services/common/async.js @@ -80,5 @@ > onComplete.state = CB_FAIL; > onComplete.value = data; > - > - // Cause the caller to get an exception and stop execution. > - throw data; Let's document this behavior at the top of the method.
Attachment #8425143 - Flags: feedback?(rnewman) → feedback+
(In reply to Richard Newman [:rnewman] from comment #8) > It worries me that this doesn't cause any test failures. Not quite sure what you mean here, but try at https://tbpl.mozilla.org/?tree=Try&rev=a51e9ca4e5e0 > Let's document this behavior at the top of the method. Done
Attachment #8422858 - Attachment is obsolete: true
Attachment #8425143 - Attachment is obsolete: true
Attachment #8428437 - Flags: review?(rnewman)
Whiteboard: p=2 s=it-32c-31a-30b.2 [qa-] → p=2 s=it-32c-31a-30b.3 [qa-]
Comment on attachment 8428437 [details] [diff] [review] 0001-Prevent-async-callback-from-throwing-when-a-callback.patch Review of attachment 8428437 [details] [diff] [review]: ----------------------------------------------------------------- By "worries me" I mean that we're evidently not testing the failure paths enough, else you would have had to fix some tests that were expecting an exception!
Attachment #8428437 - Flags: review?(rnewman) → review+
Let's take this for 32, making sure that TPS is happy, and getting some manual QA for whatever error approaches are possible to induce by hand.
Component: FxAccounts → Firefox: Common
Product: Core → Mozilla Services
Summary: TEST-UNEXPECTED-FAIL | resource://gre/modules/services-common/tokenserverclient.js | A promise chain failed to handle a rejection: TokenServerClientServerError({"now":"2014-05-13T15:03:33.823Z","message":"Non-JSON response.","cause":"malformed-response", → Sync spinning callback error path throws in two places, causing unhandled promise rejections and potential terror
Whiteboard: p=2 s=it-32c-31a-30b.3 [qa-] → p=2 s=it-32c-31a-30b.3 [qa+]
Status: ASSIGNED → RESOLVED
Closed: 11 years ago
Resolution: --- → FIXED
Target Milestone: --- → mozilla32
Assigning to Tracy for verification, since this is related to Sync.
QA Contact: twalker
Hi Tracy, will it be possible to have this bug verified by end of day this Friday? Our current Iteration ends on Monday June 9.
Flags: needinfo?(twalker)
(In reply to Marco Mucci [:MarcoM] from comment #15) > Hi Tracy, will it be possible to have this bug verified by end of day this > Friday? Our current Iteration ends on Monday June 9. Yes, but this one is clear cut reproducible, indicated by the initial [qa-]. rnewman, what can trigger this potential terror manually on the client side here? no network?
We've always used [qa-] as "doesn't need QA" (usually covered by tests). [qa+] means "please test this for me".
rnewman, sorry, my statement was missing "not" as in "is *not* clear cut reproducible." Thus why I asked for guidance to reproduce. I don't know what callback rejections and unhandled promise rejections are. So I don't know what to be testing for here.
Flags: needinfo?(twalker)
(In reply to [:tracy] Tracy Walker - QA Mentor from comment #18) > rnewman, sorry, my statement was missing "not" as in "is *not* clear cut > reproducible." Gotcha. > Thus why I asked for guidance to reproduce. I don't know what callback > rejections and unhandled promise rejections are. So I don't know what to be > testing for here. This patch affects handling of internal error flows. If you have a way of testing a corrupt bookmark DB, a non-functioning passwords DB (e.g., install Keychain Services Integration add-on), or network errors, just make sure that behavior hasn't changed.
Whiteboard: p=2 s=it-32c-31a-30b.3 [qa+] → p=2 s=33.1 [qa+]
Hey Kairo, with Tracy on PTO can this bug be reassigned to another QA contact for verification.
Iteration: --- → 33.2
Points: --- → 2
Flags: needinfo?(kairo)
Whiteboard: p=2 s=33.1 [qa+] → [qa+]
Per Firefox QA meeting, forwarding this to Kevin for now. Marco, thanks for spotting this!
Flags: needinfo?(kairo)
QA Contact: twalker → kbrosnan
Hi Kevin, the desktop iteration ends on Monday. Is it possible to have this bug verified by then.
Flags: needinfo?(kbrosnan)
Iteration: 33.2 → 33.3
I looked into this to be able to verify this I would need a subtly corrupted sqlite database based on comment 19. I have created several corrupt databases however Firefox detects them at startup and moves them to .corrupt files. So unless Tracy has such a file we won't be able to verify this issue.
Flags: needinfo?(kbrosnan)
I checked this fix this morning by installing the add-on rnewman suggested. With the add-on enabled, Syncing gets the encountered an error message bar with the following in the log. 1405347201740 Sync.ErrorHandler DEBUG passwords failed: TypeError: Services.logins is undefined (resource://gre/modules/services-sync/engines/passwords.js:162:8) JS Stack trace: PasswordStore__getAllIDs@passwords.js:162:9 < SyncEngine.prototype._syncStartup@engines.js:884:22 < SyncEngine.prototype._sync@engines.js:1479:7 < WrappedNotify@util.js:141:21 < Engine.prototype.sync@engines.js:655:5 < _syncEngine@enginesync.js:199:7 < sync@enginesync.js:149:15 < onNotify@service.js:1271:7 < WrappedNotify@util.js:141:21 < WrappedLock@util.js:96:16 < _lockedSync@service.js:1261:12 < sync/<@service.js:1253:14 < WrappedCatch@util.js:70:16 < sync@service.js:1241:5 <snip> 1405347202058 Sync.Synchronizer INFO Sync completed at 2014-07-14 09:13:22 after 0.87 secs. 1405347202059 Sync.Declined DEBUG Handling remote declined: ["passwords"] 1405347202059 Sync.Declined DEBUG Handling local declined: [] 1405347202059 Sync.Declined DEBUG Declined changed? true 1405347202059 Sync.Service DEBUG Uploading meta/global: {"payload":"{\"syncID\":\"Wd0jgDsvVqLT\",\"storageVersion\":5,\"declined\":[],\"engines\":{\"clients\":{\"version\":1,\"syncID\":\"AN0PscwpQmYJ\"},\"bookmarks\":{\"version\":2,\"syncID\":\"dDcjb5qILv7R\"},\"forms\":{\"version\":1,\"syncID\":\"Zwh_LTALGv9M\"},\"history\":{\"version\":1,\"syncID\":\"_ifP_Qibx7Pe\"},\"prefs\":{\"version\":2,\"syncID\":\"WFBxpS7p448T\"},\"tabs\":{\"version\":1,\"syncID\":\"N_W7KkI8x9gO\"},\"addons\":{\"version\":1,\"syncID\":\"VkMM6mkTdaj7\"},\"passwords\":{\"version\":1,\"syncID\":\"AkW4is88t7Fh\"}}}","modified":1400522058.97,"id":"global"} 1405347202060 Sync.BrowserIDManager DEBUG _ensureValidToken already has one 1405347202060 Sync.Resource DEBUG PUT Length: 577 1405347202156 Sync.Resource DEBUG mesg: PUT success 200 https://sync-34-us-west-2.sync.services.mozilla.com/1.5/1407510/storage/meta/global 1405347202156 Sync.Resource DEBUG PUT success 200 https://sync-34-us-west-2.sync.services.mozilla.com/1.5/1407510/storage/meta/global 1405347202158 Sync.SyncScheduler DEBUG Next sync in 90000 ms. 1405347202158 Sync.ErrorHandler DEBUG Some engines did not sync correctly. I think this is now expected.
Status: RESOLVED → VERIFIED
Whiteboard: [qa+] → [qa!]
Marco: we should drop this from the backlog while Mark is away.
Flags: needinfo?(mmucci)
Er, I misread! Nevermind!
Flags: needinfo?(mmucci)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: