-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Sync cloud integration on Authorization problems #4324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
eb468fa
to
fd28d05
Compare
fd28d05
to
500523d
Compare
500523d
to
3ce2c47
Compare
3ce2c47
to
c962bd0
Compare
this.syncCountDueToRequestException++; | ||
this._session = { | ||
...this._session, | ||
expiresAt: new Date(Date.now() - 1), | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have a hypothetical scenario I want to check with you here.
Let's say I have a GitHub token which has the required scopes to get my current account but not the scopes to get PRs.
So, every time the Launchpad automatically fetches PRs (let's say, every 5 minutes), it first gets the current account, which succeeds (and also resets the sync count) and then it tries to get PRs and fails because of the scope issue, throws an AuthenticationError, and we force it to sync.
This would cause us to sync every time the Launchpad fetches PRs which would hit our backend pretty hard and probably is not the intention, but..is it possible? If we can confirm that I am worrying for nothing, I think we are ok to merge.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes sense. It's hard to reproduce, probably should be reproduced on a self-hosted server where the integration is connected using PAT.
Anyway, I've implemented the fix here: 4e1b411 when a success in one use-case doesn't cancel failure in another case, so we avoid continuous syncing.
Also I've noticed that when GKDev keeps returning expired key we keep refreshing it in refreshSessionIfExpired()
, so I added another fix: 3c06400
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better solution for unsuccessful syncing of expired tokens: b178a03
a1bdad6
to
9bcdaad
Compare
9bcdaad
to
3c06400
Compare
3c06400
to
3e099e9
Compare
3e099e9
to
b178a03
Compare
return { value: pullRequests, duration: Date.now() - start }; | ||
} catch (ex) { | ||
Logger.error(ex, scope); | ||
return { error: ex, duration: Date.now() - start }; | ||
return this.handleProviderException('searchMyPullRequests', ex, scope, { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I'm catching this a bit late, but: we moved searchMyPullRequests
off of handleProviderException
on purpose, specifically because it results in an error notification in VS Code if the user errors too many times, and folks whose integration was having issues with Launchpad (due to too many PRs, large/complex repos, etc.) were seeing the notification all the time since Launchpad query automatically runs in an interval.
We need to make sure we do not send a message in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
RE: we moved searchMyPullRequests off of handleProviderException on purpose, specifically because it results in an error notification in VS Code if the user errors too many times, and folks whose integration was having issues with Launchpad (due to too many PRs, large/complex repos, etc.)
What do you think about adding silent
flag: b4db45d ?
(It's done after a little refactoring: 07116b4)
if (ex instanceof CancellationError) return defaultValue; | ||
|
||
Logger.error(ex, scope); | ||
|
||
if (ex instanceof AuthenticationError || ex instanceof RequestClientError) { | ||
if (ex instanceof AuthenticationError && this._session?.cloud) { | ||
if (!this.hasSessionSyncRequests()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just want to note here that once we have a "session sync request" for a particular case like "getIssuesForProject", we will not pass this check again until either:
- that specific function has had a chance to run successfully, or
- the integration disconnects
So for a three hour session, if the token lasts an hour and we run into this once for some specific query, we will go back to the default non-sync failures for other queries if that specific query is not used again after syncing the first time.
Not a big deal I suppose, and not sure there is a perfect solution here - just making sure we are aware of the limitations even though this is better than the previous version,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we will not pass this check again until either:
What do you think about this: add09cc
It should work like this:
- we detect an auth error on
getIssuesForProject
- we expire it locally in our memory to force it resync
- Then one of the following happens:
- if it's not actually expired GK.dev returns us the same token, so we don't reset the flags
- if GK.dev refreshes token and returns a new one, we reset all the flags, to be able to see how it works.
I haven't tested it thoroughly yet, but if you approve the approach I go ahead with it.
b178a03
to
d109abd
Compare
- The `handleProviderException` method in `IntegrationBase` is updated to accept an options object instead of individual parameters. - The method now only returns void, requiring the calling functions to return the default value themselves. (#4324)
Resets the request exception count when a new access token is obtained after refreshing the session. This prevents the integration from being prematurely disconnected due to request errors associated with the old token. (#4324)
Description
Here we sync the cloud connected integration with GKDev when we face an authorization problem hoping that during the sync they respond us with the actual token.
If we see that we keep facing the same error we don't try to sync again. Instead we disconnect the integration soon letting user know that they need to take an action to reconnect.
Related to:
Follow-ups:
Checklist
Fixes $XXX -
orCloses #XXX -
prefix to auto-close the issue that your PR addresses