Skip to content

Commit

Permalink
Add fallback/cutoff to our backend calls similar to how we handle Git…
Browse files Browse the repository at this point in the history
…Hub queries #3519 (#3494)

* Handles errors of GKDev API and Code suggestions (drafts)
(#3494, #3519)

* Makes Provider-related errors more generic, e.g. drops provider prefix
(#3494, #3519)

* Counts exceptions of GK API and drops current session if gets too many
(#3494, #3519)

* Handles more different error types differently
(#3494, #3519)

* Handle exception on reactivating ProTrial
(#3494, #3519)

* Checks unsuccessful response on rate limits and timeouts to pause them
(#3494, #3519)

* Create GK scoped "show message/error" functions
(#3494, #3519)
  • Loading branch information
sergeibbb authored Sep 13, 2024
1 parent 2219c30 commit 157a902
Show file tree
Hide file tree
Showing 9 changed files with 325 additions and 81 deletions.
3 changes: 3 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,9 @@ export type SuppressedMessages =
| 'suppressLineUncommittedWarning'
| 'suppressNoRepositoryWarning'
| 'suppressRebaseSwitchToTextWarning'
| 'suppressGkDisconnectedTooManyFailedRequestsWarningMessage'
| 'suppressGkRequestFailed500Warning'
| 'suppressGkRequestTimedOutWarning'
| 'suppressIntegrationDisconnectedTooManyFailedRequestsWarning'
| 'suppressIntegrationRequestFailed500Warning'
| 'suppressIntegrationRequestTimedOutWarning'
Expand Down
38 changes: 31 additions & 7 deletions src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,30 +210,54 @@ export class ProviderNotFoundError extends Error {
}
}

export class ProviderRequestClientError extends Error {
export class RequestClientError extends Error {
constructor(public readonly original: Error) {
super(original.message);

Error.captureStackTrace?.(this, ProviderRequestClientError);
Error.captureStackTrace?.(this, RequestClientError);
}
}

export class ProviderRequestNotFoundError extends Error {
export class RequestNotFoundError extends Error {
constructor(public readonly original: Error) {
super(original.message);

Error.captureStackTrace?.(this, ProviderRequestNotFoundError);
Error.captureStackTrace?.(this, RequestNotFoundError);
}
}

export class ProviderRequestRateLimitError extends Error {
export class RequestRateLimitError extends Error {
constructor(
public readonly original: Error,
public readonly token: string,
public readonly token: string | undefined,
public readonly resetAt: number | undefined,
) {
super(original.message);

Error.captureStackTrace?.(this, ProviderRequestRateLimitError);
Error.captureStackTrace?.(this, RequestRateLimitError);
}
}

export class RequestGoneError extends Error {
constructor(public readonly original: Error) {
super(original.message);

Error.captureStackTrace?.(this, RequestGoneError);
}
}

export class RequestUnprocessableEntityError extends Error {
constructor(public readonly original: Error) {
super(original.message);

Error.captureStackTrace?.(this, RequestUnprocessableEntityError);
}
}

export class RequestsAreBlockedTemporarilyError extends Error {
constructor() {
super('Requests are blocked');

Error.captureStackTrace?.(this, RequestsAreBlockedTemporarilyError);
}
}
24 changes: 24 additions & 0 deletions src/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,30 @@ export function showRebaseSwitchToTextWarningMessage(): Promise<MessageItem | un
);
}

export function showGkDisconnectedTooManyFailedRequestsWarningMessage(): Promise<MessageItem | undefined> {
return showMessage(
'error',
`Requests to GitKraken have stopped being sent for this session, because of too many failed requests.`,
'suppressGkDisconnectedTooManyFailedRequestsWarningMessage',
undefined,
{
title: 'OK',
},
);
}

export function showGkRequestFailed500WarningMessage(message: string): Promise<MessageItem | undefined> {
return showMessage('error', message, 'suppressGkRequestFailed500Warning', undefined, {
title: 'OK',
});
}

export function showGkRequestTimedOutWarningMessage(): Promise<MessageItem | undefined> {
return showMessage('error', `GitKraken request timed out.`, 'suppressGkRequestTimedOutWarning', undefined, {
title: 'OK',
});
}

export function showIntegrationDisconnectedTooManyFailedRequestsWarningMessage(
providerName: string,
): Promise<MessageItem | undefined> {
Expand Down
37 changes: 28 additions & 9 deletions src/plus/gk/account/subscriptionService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import type { CoreColors } from '../../../constants.colors';
import { Commands } from '../../../constants.commands';
import type { Source, TrackingContext } from '../../../constants.telemetry';
import type { Container } from '../../../container';
import { AccountValidationError } from '../../../errors';
import { AccountValidationError, RequestsAreBlockedTemporarilyError } from '../../../errors';
import type { RepositoriesChangeEvent } from '../../../git/gitProviderService';
import { executeCommand, registerCommand } from '../../../system/command';
import { configuration } from '../../../system/configuration';
Expand Down Expand Up @@ -418,6 +418,7 @@ export class SubscriptionService implements Disposable {
}

private async logoutCore(reset: boolean = false): Promise<void> {
this.connection.resetRequestExceptionCount();
this._lastValidatedDate = undefined;
if (this._validationTimer != null) {
clearInterval(this._validationTimer);
Expand Down Expand Up @@ -497,24 +498,41 @@ export class SubscriptionService implements Disposable {
const session = await this.ensureSession(false);
if (session == null) return;

const rsp = await this.connection.fetchApi('user/reactivate-trial', {
method: 'POST',
body: JSON.stringify({ client: 'gitlens' }),
});
try {
const rsp = await this.connection.fetchApi('user/reactivate-trial', {
method: 'POST',
body: JSON.stringify({ client: 'gitlens' }),
});

if (!rsp.ok) {
if (rsp.status === 409) {
void window.showErrorMessage(
'You are not eligible to reactivate your Pro trial. If you feel that is an error, please contact support.',
'OK',
);
return;
}

if (!rsp.ok) {
if (rsp.status === 409) {
void window.showErrorMessage(
'You are not eligible to reactivate your Pro trial. If you feel that is an error, please contact support.',
`Unable to reactivate trial: (${rsp.status}) ${rsp.statusText}. Please try again. If this issue persists, please contact support.`,
'OK',
);
return;
}
} catch (ex) {
if (ex instanceof RequestsAreBlockedTemporarilyError) {
void window.showErrorMessage(
'Unable to reactivate trial: Too many failed requests. Please reload the window and try again.',
'OK',
);
return;
}

void window.showErrorMessage(
`Unable to reactivate trial: (${rsp.status}) ${rsp.statusText}. Please try again. If this issue persists, please contact support.`,
`Unable to reactivate trial. Please try again. If this issue persists, please contact support.`,
'OK',
);
Logger.error(ex, scope);
return;
}

Expand Down Expand Up @@ -1161,6 +1179,7 @@ export class SubscriptionService implements Disposable {
}
}

this.connection.resetRequestExceptionCount();
return session;
}

Expand Down
Loading

0 comments on commit 157a902

Please sign in to comment.