Skip to content

Fix various post sign out requests + bugs#1075

Merged
marcaaron merged 9 commits intomasterfrom
marcaaron-preventQueued
Dec 30, 2020
Merged

Fix various post sign out requests + bugs#1075
marcaaron merged 9 commits intomasterfrom
marcaaron-preventQueued

Conversation

@marcaaron
Copy link
Contributor

@Julesssss @tgolen

Details

There are a few login bugs that I noticed while testing the sign in / sign out flows and I'm addressing them all here.

Fixed Issues

Fixes https://github.com/Expensify/Expensify/issues/148468

Tests

  1. Log in
  2. Quickly log out
  3. Verify you can safely log in again and there are no endless requests being made on a loop in the JS console

Screenshots

@marcaaron marcaaron requested a review from a team as a code owner December 23, 2020 16:50
@marcaaron marcaaron self-assigned this Dec 23, 2020
@github-actions
Copy link
Contributor

github-actions bot commented Dec 23, 2020

CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅

@botify botify requested review from Gonals and removed request for a team December 23, 2020 16:50
// make this request at all and clear the request queue
networkRequestQueue = [];
return;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't do this we'll allow a request to be made that can't possibly succeed so it's better that we never make it at all.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If someone adds another throw inside enhanceParameters, or there is some kind of bug that gets introduced that throws an unexpected error, it's not clear that this will cause the network queue to be cleared. I'd rather be very explicit about how this work by doing maybe one of these solutions:

  1. Have a method Network.clearRequestQueue() that is called in place of the throw new Error('A request was made without an authToken');. I'd prefer this one because it's very clear what the intention of the code is.
  2. Have specific checking here on err to only clear the request queue when the A request was made without an authToken error is thrown. I don't like this as much because if I were just looking at addAuthTokenToParameters I wouldn't know that clearing the network queue could be a side-effect of throwing an error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, that's a valid concern. The problem with 1 if that we probably don't need to make any request if we have no authToken. Clearing the network request queue alone doesn't achieve this since we are already making this request on the next line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will think about this some more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I got a better solution. We will:

  1. Clear and pause the request queue via addAuthTokenToParameters()
  2. Check to see if calling enhanceParameters() paused the queue and return early

// A report can be missing a name if a comment is received via pusher event
// and the report does not yet exist in Onyx (eg. a new DM created with the logged in person)
if (report.reportName === undefined) {
if (report.reportID && report.reportName === undefined) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In some cases, report data will show up first without a reportID and no reportName. In those cases, we should not attempt to fetch a report that has no reportID

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we attempt to fetch data with ReportID but undefined reportName?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah so, it's completely OK to do that (see the comment above) and in fact we want to because we might be handling a report comment from Pusher and we need to download it. Reports that we've downloaded already should have some kind of report name in storage. This is a little weird but it's just how it works for now. Maybe in the future we will fix this to make it more obvious that a report has not been fetched from the server and won't use the reportName implementation detail.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would it be possible for there to be a report without a reportID? Especially since the Onyx key uses the report ID in the name of the key?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In theory, this could happen anytime we call merge() for a report that doesn't exist without also including the reportID. I'm not exactly sure what situation leads to that happening here, but this seems like a safe way to avoid calling an API that is guaranteed to fail.

// If we have an old login for some reason, we should delete it before storing the new details
if (credentials.login) {
API.DeleteLogin({
authToken: authenticateResponse.authToken,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seemed to be failing due to not having an authToken despite authenticating just prior.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be avoided and I would rather dig into why the authToken sent with the DeleteLogin request is incorrect. Maybe this is what we are discussing in this slack thread today?

@Julesssss
Copy link
Contributor

Ran out of time today, will have to review tomorrow morning.

@marcaaron marcaaron requested a review from tgolen December 23, 2020 21:22
Julesssss
Julesssss previously approved these changes Dec 24, 2020
Copy link
Contributor

@Gonals Gonals left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, just one question!

@marcaaron marcaaron requested a review from Gonals December 24, 2020 19:31
Gonals
Gonals previously approved these changes Dec 28, 2020
@Gonals
Copy link
Contributor

Gonals commented Dec 28, 2020

@tgolen All yours!

// make this request at all and clear the request queue
networkRequestQueue = [];
return;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If someone adds another throw inside enhanceParameters, or there is some kind of bug that gets introduced that throws an unexpected error, it's not clear that this will cause the network queue to be cleared. I'd rather be very explicit about how this work by doing maybe one of these solutions:

  1. Have a method Network.clearRequestQueue() that is called in place of the throw new Error('A request was made without an authToken');. I'd prefer this one because it's very clear what the intention of the code is.
  2. Have specific checking here on err to only clear the request queue when the A request was made without an authToken error is thrown. I don't like this as much because if I were just looking at addAuthTokenToParameters I wouldn't know that clearing the network queue could be a side-effect of throwing an error.

// A report can be missing a name if a comment is received via pusher event
// and the report does not yet exist in Onyx (eg. a new DM created with the logged in person)
if (report.reportName === undefined) {
if (report.reportID && report.reportName === undefined) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would it be possible for there to be a report without a reportID? Especially since the Onyx key uses the report ID in the name of the key?

// If we have an old login for some reason, we should delete it before storing the new details
if (credentials.login) {
API.DeleteLogin({
authToken: authenticateResponse.authToken,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should be avoided and I would rather dig into why the authToken sent with the DeleteLogin request is incorrect. Maybe this is what we are discussing in this slack thread today?

@marcaaron marcaaron dismissed stale reviews from Gonals and Julesssss via 75fbb0f December 29, 2020 00:10
@marcaaron marcaaron requested a review from tgolen December 29, 2020 00:42
@marcaaron
Copy link
Contributor Author

Updated this one.

Copy link
Contributor

@tgolen tgolen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool, I like how you solved that. It's a little awkward to see a double-check for the queue being paused, but the comment you added clarifies why it's necessary and I don't see any other way around it.

@marcaaron marcaaron requested a review from tgolen December 29, 2020 18:51
@marcaaron
Copy link
Contributor Author

Updated

@marcaaron marcaaron merged commit 53148ca into master Dec 30, 2020
@marcaaron marcaaron deleted the marcaaron-preventQueued branch December 30, 2020 22:31
@github-actions github-actions bot locked and limited conversation to collaborators Dec 30, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants