Skip to content

Commit 157a902

Browse files
authored
Add fallback/cutoff to our backend calls similar to how we handle GitHub 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)
1 parent 2219c30 commit 157a902

File tree

9 files changed

+325
-81
lines changed

9 files changed

+325
-81
lines changed

src/config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,9 @@ export type SuppressedMessages =
589589
| 'suppressLineUncommittedWarning'
590590
| 'suppressNoRepositoryWarning'
591591
| 'suppressRebaseSwitchToTextWarning'
592+
| 'suppressGkDisconnectedTooManyFailedRequestsWarningMessage'
593+
| 'suppressGkRequestFailed500Warning'
594+
| 'suppressGkRequestTimedOutWarning'
592595
| 'suppressIntegrationDisconnectedTooManyFailedRequestsWarning'
593596
| 'suppressIntegrationRequestFailed500Warning'
594597
| 'suppressIntegrationRequestTimedOutWarning'

src/errors.ts

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -210,30 +210,54 @@ export class ProviderNotFoundError extends Error {
210210
}
211211
}
212212

213-
export class ProviderRequestClientError extends Error {
213+
export class RequestClientError extends Error {
214214
constructor(public readonly original: Error) {
215215
super(original.message);
216216

217-
Error.captureStackTrace?.(this, ProviderRequestClientError);
217+
Error.captureStackTrace?.(this, RequestClientError);
218218
}
219219
}
220220

221-
export class ProviderRequestNotFoundError extends Error {
221+
export class RequestNotFoundError extends Error {
222222
constructor(public readonly original: Error) {
223223
super(original.message);
224224

225-
Error.captureStackTrace?.(this, ProviderRequestNotFoundError);
225+
Error.captureStackTrace?.(this, RequestNotFoundError);
226226
}
227227
}
228228

229-
export class ProviderRequestRateLimitError extends Error {
229+
export class RequestRateLimitError extends Error {
230230
constructor(
231231
public readonly original: Error,
232-
public readonly token: string,
232+
public readonly token: string | undefined,
233233
public readonly resetAt: number | undefined,
234234
) {
235235
super(original.message);
236236

237-
Error.captureStackTrace?.(this, ProviderRequestRateLimitError);
237+
Error.captureStackTrace?.(this, RequestRateLimitError);
238+
}
239+
}
240+
241+
export class RequestGoneError extends Error {
242+
constructor(public readonly original: Error) {
243+
super(original.message);
244+
245+
Error.captureStackTrace?.(this, RequestGoneError);
246+
}
247+
}
248+
249+
export class RequestUnprocessableEntityError extends Error {
250+
constructor(public readonly original: Error) {
251+
super(original.message);
252+
253+
Error.captureStackTrace?.(this, RequestUnprocessableEntityError);
254+
}
255+
}
256+
257+
export class RequestsAreBlockedTemporarilyError extends Error {
258+
constructor() {
259+
super('Requests are blocked');
260+
261+
Error.captureStackTrace?.(this, RequestsAreBlockedTemporarilyError);
238262
}
239263
}

src/messages.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,30 @@ export function showRebaseSwitchToTextWarningMessage(): Promise<MessageItem | un
160160
);
161161
}
162162

163+
export function showGkDisconnectedTooManyFailedRequestsWarningMessage(): Promise<MessageItem | undefined> {
164+
return showMessage(
165+
'error',
166+
`Requests to GitKraken have stopped being sent for this session, because of too many failed requests.`,
167+
'suppressGkDisconnectedTooManyFailedRequestsWarningMessage',
168+
undefined,
169+
{
170+
title: 'OK',
171+
},
172+
);
173+
}
174+
175+
export function showGkRequestFailed500WarningMessage(message: string): Promise<MessageItem | undefined> {
176+
return showMessage('error', message, 'suppressGkRequestFailed500Warning', undefined, {
177+
title: 'OK',
178+
});
179+
}
180+
181+
export function showGkRequestTimedOutWarningMessage(): Promise<MessageItem | undefined> {
182+
return showMessage('error', `GitKraken request timed out.`, 'suppressGkRequestTimedOutWarning', undefined, {
183+
title: 'OK',
184+
});
185+
}
186+
163187
export function showIntegrationDisconnectedTooManyFailedRequestsWarningMessage(
164188
providerName: string,
165189
): Promise<MessageItem | undefined> {

src/plus/gk/account/subscriptionService.ts

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import type { CoreColors } from '../../../constants.colors';
2626
import { Commands } from '../../../constants.commands';
2727
import type { Source, TrackingContext } from '../../../constants.telemetry';
2828
import type { Container } from '../../../container';
29-
import { AccountValidationError } from '../../../errors';
29+
import { AccountValidationError, RequestsAreBlockedTemporarilyError } from '../../../errors';
3030
import type { RepositoriesChangeEvent } from '../../../git/gitProviderService';
3131
import { executeCommand, registerCommand } from '../../../system/command';
3232
import { configuration } from '../../../system/configuration';
@@ -418,6 +418,7 @@ export class SubscriptionService implements Disposable {
418418
}
419419

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

500-
const rsp = await this.connection.fetchApi('user/reactivate-trial', {
501-
method: 'POST',
502-
body: JSON.stringify({ client: 'gitlens' }),
503-
});
501+
try {
502+
const rsp = await this.connection.fetchApi('user/reactivate-trial', {
503+
method: 'POST',
504+
body: JSON.stringify({ client: 'gitlens' }),
505+
});
506+
507+
if (!rsp.ok) {
508+
if (rsp.status === 409) {
509+
void window.showErrorMessage(
510+
'You are not eligible to reactivate your Pro trial. If you feel that is an error, please contact support.',
511+
'OK',
512+
);
513+
return;
514+
}
504515

505-
if (!rsp.ok) {
506-
if (rsp.status === 409) {
507516
void window.showErrorMessage(
508-
'You are not eligible to reactivate your Pro trial. If you feel that is an error, please contact support.',
517+
`Unable to reactivate trial: (${rsp.status}) ${rsp.statusText}. Please try again. If this issue persists, please contact support.`,
518+
'OK',
519+
);
520+
return;
521+
}
522+
} catch (ex) {
523+
if (ex instanceof RequestsAreBlockedTemporarilyError) {
524+
void window.showErrorMessage(
525+
'Unable to reactivate trial: Too many failed requests. Please reload the window and try again.',
509526
'OK',
510527
);
511528
return;
512529
}
513530

514531
void window.showErrorMessage(
515-
`Unable to reactivate trial: (${rsp.status}) ${rsp.statusText}. Please try again. If this issue persists, please contact support.`,
532+
`Unable to reactivate trial. Please try again. If this issue persists, please contact support.`,
516533
'OK',
517534
);
535+
Logger.error(ex, scope);
518536
return;
519537
}
520538

@@ -1161,6 +1179,7 @@ export class SubscriptionService implements Disposable {
11611179
}
11621180
}
11631181

1182+
this.connection.resetRequestExceptionCount();
11641183
return session;
11651184
}
11661185

0 commit comments

Comments
 (0)