diff --git a/src/config.ts b/src/config.ts index a7a62cdf743d8..af834850bd4df 100644 --- a/src/config.ts +++ b/src/config.ts @@ -589,6 +589,9 @@ export type SuppressedMessages = | 'suppressLineUncommittedWarning' | 'suppressNoRepositoryWarning' | 'suppressRebaseSwitchToTextWarning' + | 'suppressGkDisconnectedTooManyFailedRequestsWarningMessage' + | 'suppressGkRequestFailed500Warning' + | 'suppressGkRequestTimedOutWarning' | 'suppressIntegrationDisconnectedTooManyFailedRequestsWarning' | 'suppressIntegrationRequestFailed500Warning' | 'suppressIntegrationRequestTimedOutWarning' diff --git a/src/errors.ts b/src/errors.ts index 74ff4f61b9df3..abbcf7da81e6f 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -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); } } diff --git a/src/messages.ts b/src/messages.ts index f9703ddf00948..dba78f7ce344b 100644 --- a/src/messages.ts +++ b/src/messages.ts @@ -160,6 +160,30 @@ export function showRebaseSwitchToTextWarningMessage(): Promise { + 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 { + return showMessage('error', message, 'suppressGkRequestFailed500Warning', undefined, { + title: 'OK', + }); +} + +export function showGkRequestTimedOutWarningMessage(): Promise { + return showMessage('error', `GitKraken request timed out.`, 'suppressGkRequestTimedOutWarning', undefined, { + title: 'OK', + }); +} + export function showIntegrationDisconnectedTooManyFailedRequestsWarningMessage( providerName: string, ): Promise { diff --git a/src/plus/gk/account/subscriptionService.ts b/src/plus/gk/account/subscriptionService.ts index 89906159c1729..29f64ebe43701 100644 --- a/src/plus/gk/account/subscriptionService.ts +++ b/src/plus/gk/account/subscriptionService.ts @@ -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'; @@ -418,6 +418,7 @@ export class SubscriptionService implements Disposable { } private async logoutCore(reset: boolean = false): Promise { + this.connection.resetRequestExceptionCount(); this._lastValidatedDate = undefined; if (this._validationTimer != null) { clearInterval(this._validationTimer); @@ -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; } @@ -1161,6 +1179,7 @@ export class SubscriptionService implements Disposable { } } + this.connection.resetRequestExceptionCount(); return session; } diff --git a/src/plus/gk/serverConnection.ts b/src/plus/gk/serverConnection.ts index 854e646e8135d..77ebc24202005 100644 --- a/src/plus/gk/serverConnection.ts +++ b/src/plus/gk/serverConnection.ts @@ -1,12 +1,31 @@ -import type { CancellationToken, Disposable } from 'vscode'; -import { version as codeVersion, env, Uri } from 'vscode'; +import type { RequestError } from '@octokit/request-error'; +import type { CancellationToken } from 'vscode'; +import { version as codeVersion, env, Uri, window } from 'vscode'; import type { HeadersInit, RequestInfo, RequestInit, Response } from '@env/fetch'; import { fetch as _fetch, getProxyAgent } from '@env/fetch'; import { getPlatform } from '@env/platform'; +import type { Disposable } from '../../api/gitlens'; import type { Container } from '../../container'; -import { AuthenticationRequiredError, CancellationError } from '../../errors'; +import { + AuthenticationError, + AuthenticationErrorReason, + AuthenticationRequiredError, + CancellationError, + RequestClientError, + RequestGoneError, + RequestNotFoundError, + RequestRateLimitError, + RequestsAreBlockedTemporarilyError, + RequestUnprocessableEntityError, +} from '../../errors'; +import { + showGkDisconnectedTooManyFailedRequestsWarningMessage, + showGkRequestFailed500WarningMessage, + showGkRequestTimedOutWarningMessage, +} from '../../messages'; import { memoize } from '../../system/decorators/memoize'; import { Logger } from '../../system/logger'; +import type { LogScope } from '../../system/logger.scope'; import { getLogScope } from '../../system/logger.scope'; interface FetchOptions { @@ -135,6 +154,9 @@ export class ServerConnection implements Disposable { } private async gkFetch(url: RequestInfo, init?: RequestInit, options?: GKFetchOptions): Promise { + if (this.requestsAreBlocked) { + throw new RequestsAreBlockedTemporarilyError(); + } const scope = getLogScope(); try { @@ -169,9 +191,8 @@ export class ServerConnection implements Disposable { url = `${url}?${options.query}`; } } - // TODO@eamodio handle common response errors - return this.fetch( + const rsp = await this.fetch( url, { ...init, @@ -179,18 +200,171 @@ export class ServerConnection implements Disposable { }, options, ); + if (!rsp.ok) { + await this.handleGkUnsuccessfulResponse(rsp, scope); + } else { + this.resetRequestExceptionCount(); + } + return rsp; } catch (ex) { - Logger.error(ex, scope); + this.handleGkRequestError('gitkraken', ex, scope); throw ex; } } + private buildRequestRateLimitError(token: string | undefined, ex: RequestError) { + let resetAt: number | undefined; + + const reset = ex.response?.headers?.['x-ratelimit-reset']; + if (reset != null) { + resetAt = parseInt(reset, 10); + if (Number.isNaN(resetAt)) { + resetAt = undefined; + } + } + return new RequestRateLimitError(ex, token, resetAt); + } + + private async handleGkUnsuccessfulResponse(rsp: Response, scope: LogScope | undefined): Promise { + // Too Many Requests + if (rsp.status == 429) { + this.trackRequestException(); + return; + } + + // Forbidden + if (rsp.status == 403) { + if (rsp.statusText.includes('rate limit')) { + this.trackRequestException(); + } + return; + } + + // Internal Server Error + if (rsp.status == 500) { + this.trackRequestException(); + void showGkRequestFailed500WarningMessage( + 'GitKraken failed to respond and might be experiencing issues. Please visit the [GitKraken status page](https://cloud.gitkrakenstatus.com) for more information.', + ); + return; + } + + const content = await rsp.text(); + + // Bad Gateway + if (rsp.status == 502) { + Logger.error(`GitKraken request failed: ${content} (${rsp.statusText})`, scope); + if (content.includes('timeout')) { + this.trackRequestException(); + void showGkRequestTimedOutWarningMessage(); + } + return; + } + + // Service Unavailable + if (rsp.status == 503) { + Logger.error(`GitKraken request failed: ${content} (${rsp.statusText})`, scope); + this.trackRequestException(); + void showGkRequestFailed500WarningMessage( + 'GitKraken failed to respond and might be experiencing issues. Please visit the [GitKraken status page](https://cloud.gitkrakenstatus.com) for more information.', + ); + return; + } + + if (rsp.status >= 400 && rsp.status < 500) { + return; + } + + if (Logger.isDebugging) { + void window.showErrorMessage(`GitKraken request failed: ${content} (${rsp.statusText})`); + } + } + + private handleGkRequestError( + token: string | undefined, + ex: RequestError | (Error & { name: 'AbortError' }), + scope: LogScope | undefined, + ): void { + if (ex instanceof CancellationError) throw ex; + if (ex.name === 'AbortError') throw new CancellationError(ex); + + switch (ex.status) { + case 404: // Not found + throw new RequestNotFoundError(ex); + case 410: // Gone + throw new RequestGoneError(ex); + case 422: // Unprocessable Entity + throw new RequestUnprocessableEntityError(ex); + case 401: // Unauthorized + throw new AuthenticationError('gitkraken', AuthenticationErrorReason.Unauthorized, ex); + case 429: //Too Many Requests + this.trackRequestException(); + throw this.buildRequestRateLimitError(token, ex); + case 403: // Forbidden + if (ex.message.includes('rate limit')) { + this.trackRequestException(); + throw this.buildRequestRateLimitError(token, ex); + } + throw new AuthenticationError('gitkraken', AuthenticationErrorReason.Forbidden, ex); + case 500: // Internal Server Error + Logger.error(ex, scope); + if (ex.response != null) { + this.trackRequestException(); + void showGkRequestFailed500WarningMessage( + 'GitKraken failed to respond and might be experiencing issues. Please visit the [GitKraken status page](https://cloud.gitkrakenstatus.com) for more information.', + ); + } + return; + case 502: // Bad Gateway + Logger.error(ex, scope); + if (ex.message.includes('timeout')) { + this.trackRequestException(); + void showGkRequestTimedOutWarningMessage(); + } + break; + case 503: // Service Unavailable + Logger.error(ex, scope); + this.trackRequestException(); + void showGkRequestFailed500WarningMessage( + 'GitKraken failed to respond and might be experiencing issues. Please visit the [GitKraken status page](https://cloud.gitkrakenstatus.com) for more information.', + ); + return; + default: + if (ex.status >= 400 && ex.status < 500) throw new RequestClientError(ex); + break; + } + + if (Logger.isDebugging) { + void window.showErrorMessage( + `GitKraken request failed: ${(ex.response as any)?.errors?.[0]?.message ?? ex.message}`, + ); + } + } + private async getAccessToken() { const session = await this.container.subscription.getAuthenticationSession(); if (session != null) return session.accessToken; throw new AuthenticationRequiredError(); } + + private requestExceptionCount = 0; + private requestsAreBlocked = false; + + resetRequestExceptionCount(): void { + this.requestExceptionCount = 0; + this.requestsAreBlocked = false; + } + + trackRequestException(): void { + this.requestExceptionCount++; + + if (this.requestExceptionCount >= 5 && !this.requestsAreBlocked) { + void showGkDisconnectedTooManyFailedRequestsWarningMessage(); + this.requestsAreBlocked = true; + this.requestExceptionCount = 0; + } + } } export interface GraphQLRequest { diff --git a/src/plus/integrations/integration.ts b/src/plus/integrations/integration.ts index 802eb2f959a3e..d0ee9b41400f3 100644 --- a/src/plus/integrations/integration.ts +++ b/src/plus/integrations/integration.ts @@ -4,7 +4,7 @@ import type { DynamicAutolinkReference } from '../../annotations/autolinks'; import type { AutolinkReference } from '../../config'; import type { Sources } from '../../constants.telemetry'; import type { Container } from '../../container'; -import { AuthenticationError, CancellationError, ProviderRequestClientError } from '../../errors'; +import { AuthenticationError, CancellationError, RequestClientError } from '../../errors'; import type { PagedResult } from '../../git/gitProvider'; import type { Account, UnidentifiedAuthor } from '../../git/models/author'; import type { DefaultBranch } from '../../git/models/defaultBranch'; @@ -272,7 +272,7 @@ export abstract class IntegrationBase< Logger.error(ex, scope); - if (ex instanceof AuthenticationError || ex instanceof ProviderRequestClientError) { + if (ex instanceof AuthenticationError || ex instanceof RequestClientError) { this.trackRequestException(); } return defaultValue; diff --git a/src/plus/integrations/providers/github/github.ts b/src/plus/integrations/providers/github/github.ts index f00775329c840..e57902bb2653f 100644 --- a/src/plus/integrations/providers/github/github.ts +++ b/src/plus/integrations/providers/github/github.ts @@ -12,9 +12,9 @@ import { AuthenticationError, AuthenticationErrorReason, CancellationError, - ProviderRequestClientError, - ProviderRequestNotFoundError, - ProviderRequestRateLimitError, + RequestClientError, + RequestNotFoundError, + RequestRateLimitError, } from '../../../../errors'; import type { PagedResult, RepositoryVisibility } from '../../../../git/gitProvider'; import type { Account, UnidentifiedAuthor } from '../../../../git/models/author'; @@ -285,7 +285,7 @@ export class GitHubApi implements Disposable { username: rsp.viewer.login ?? undefined, }; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, provider, scope); } @@ -393,7 +393,7 @@ export class GitHubApi implements Disposable { : undefined, }; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, provider, scope); } @@ -484,7 +484,7 @@ export class GitHubApi implements Disposable { username: author.login ?? undefined, }; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, provider, scope); } @@ -543,7 +543,7 @@ export class GitHubApi implements Disposable { name: defaultBranch, }; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, provider, scope); } @@ -615,7 +615,7 @@ export class GitHubApi implements Disposable { state: fromGitHubIssueOrPullRequestState(issue.state), }; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, provider, scope); } @@ -675,7 +675,7 @@ export class GitHubApi implements Disposable { return fromGitHubPullRequestLite(rsp.repository.pullRequest, provider); } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, provider, scope); } @@ -764,7 +764,7 @@ export class GitHubApi implements Disposable { return fromGitHubPullRequestLite(prs[0], provider); } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, provider, scope); } @@ -849,7 +849,7 @@ export class GitHubApi implements Disposable { return fromGitHubPullRequestLite(prs[0], provider); } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, provider, scope); } @@ -938,7 +938,7 @@ export class GitHubApi implements Disposable { : undefined, }; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, provider, scope); } @@ -1021,7 +1021,7 @@ export class GitHubApi implements Disposable { return { ranges: ranges, viewer: rsp.viewer?.name }; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return emptyBlameResult; + if (ex instanceof RequestNotFoundError) return emptyBlameResult; throw this.handleException(ex, undefined, scope); } @@ -1105,7 +1105,7 @@ export class GitHubApi implements Disposable { values: refs.nodes, }; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return emptyPagedResult; + if (ex instanceof RequestNotFoundError) return emptyPagedResult; throw this.handleException(ex, undefined, scope); } @@ -1158,7 +1158,7 @@ export class GitHubApi implements Disposable { files: result.files, }; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, undefined, scope); } @@ -1266,7 +1266,7 @@ export class GitHubApi implements Disposable { return branches; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return []; + if (ex instanceof RequestNotFoundError) return []; throw this.handleException(ex, undefined, scope); } @@ -1320,7 +1320,7 @@ export class GitHubApi implements Disposable { const count = rsp?.repository?.ref?.target.history.totalCount; return count; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, undefined, scope); } @@ -1400,7 +1400,7 @@ export class GitHubApi implements Disposable { return branches; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return []; + if (ex instanceof RequestNotFoundError) return []; throw this.handleException(ex, undefined, scope); } @@ -1549,7 +1549,7 @@ export class GitHubApi implements Disposable { viewer: rsp?.viewer.name, }; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return emptyPagedResult; + if (ex instanceof RequestNotFoundError) return emptyPagedResult; throw this.handleException(ex, undefined, scope); } @@ -1588,7 +1588,7 @@ export class GitHubApi implements Disposable { .reverse(), }; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return emptyPagedResult; + if (ex instanceof RequestNotFoundError) return emptyPagedResult; throw this.handleException(ex, undefined, scope); } @@ -1655,7 +1655,7 @@ export class GitHubApi implements Disposable { const commit = rsp.repository?.object; return commit != null ? { values: [commit], viewer: rsp.viewer.name } : emptyPagedResult; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return emptyPagedResult; + if (ex instanceof RequestNotFoundError) return emptyPagedResult; throw this.handleException(ex, undefined, scope); } @@ -1750,7 +1750,7 @@ export class GitHubApi implements Disposable { values: history.nodes, }; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, undefined, scope); } @@ -1826,7 +1826,7 @@ export class GitHubApi implements Disposable { return tags; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return []; + if (ex instanceof RequestNotFoundError) return []; throw this.handleException(ex, undefined, scope); } @@ -1911,7 +1911,7 @@ export class GitHubApi implements Disposable { const date = rsp?.repository?.object?.committer.date; return date; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, undefined, scope); } @@ -1941,7 +1941,7 @@ export class GitHubApi implements Disposable { return rsp.data; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return []; + if (ex instanceof RequestNotFoundError) return []; throw this.handleException(ex, undefined, scope); } @@ -1986,7 +1986,7 @@ export class GitHubApi implements Disposable { return rsp.repository?.defaultBranchRef?.name ?? undefined; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, undefined, scope); } @@ -2034,7 +2034,7 @@ export class GitHubApi implements Disposable { id: rsp.viewer?.id, }; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, undefined, scope); } @@ -2073,7 +2073,7 @@ export class GitHubApi implements Disposable { return result; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, undefined, scope); } @@ -2120,7 +2120,7 @@ export class GitHubApi implements Disposable { return rsp.repository.visibility === 'PUBLIC' ? 'public' : 'private'; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, undefined, scope); } @@ -2212,7 +2212,7 @@ export class GitHubApi implements Disposable { values: refs.nodes, }; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return emptyPagedResult; + if (ex instanceof RequestNotFoundError) return emptyPagedResult; throw this.handleException(ex, undefined, scope); } @@ -2304,7 +2304,7 @@ export class GitHubApi implements Disposable { ); return rsp?.repository?.object?.history.nodes?.[0]?.oid ?? undefined; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, undefined, scope); } @@ -2389,7 +2389,7 @@ export class GitHubApi implements Disposable { values: commits, }; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, undefined, scope); } @@ -2461,7 +2461,7 @@ export class GitHubApi implements Disposable { })), }; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, undefined, scope); } @@ -2523,7 +2523,7 @@ export class GitHubApi implements Disposable { if (ex instanceof GraphqlResponseError) { switch (ex.errors?.[0]?.type) { case 'NOT_FOUND': - throw new ProviderRequestNotFoundError(ex); + throw new RequestNotFoundError(ex); case 'FORBIDDEN': throw new AuthenticationError('github', AuthenticationErrorReason.Forbidden, ex); case 'RATE_LIMITED': { @@ -2537,7 +2537,7 @@ export class GitHubApi implements Disposable { } } - throw new ProviderRequestRateLimitError(ex, token, resetAt); + throw new RequestRateLimitError(ex, token, resetAt); } } @@ -2668,7 +2668,7 @@ export class GitHubApi implements Disposable { case 404: // Not found case 410: // Gone case 422: // Unprocessable Entity - throw new ProviderRequestNotFoundError(ex); + throw new RequestNotFoundError(ex); // case 429: //Too Many Requests case 401: // Unauthorized throw new AuthenticationError('github', AuthenticationErrorReason.Unauthorized, ex); @@ -2684,7 +2684,7 @@ export class GitHubApi implements Disposable { } } - throw new ProviderRequestRateLimitError(ex, token, resetAt); + throw new RequestRateLimitError(ex, token, resetAt); } throw new AuthenticationError('github', AuthenticationErrorReason.Forbidden, ex); case 500: // Internal Server Error @@ -2721,7 +2721,7 @@ export class GitHubApi implements Disposable { ); return; default: - if (ex.status >= 400 && ex.status < 500) throw new ProviderRequestClientError(ex); + if (ex.status >= 400 && ex.status < 500) throw new RequestClientError(ex); break; } diff --git a/src/plus/integrations/providers/gitlab/gitlab.ts b/src/plus/integrations/providers/gitlab/gitlab.ts index 98740e0bfcbfd..315c47975ea9d 100644 --- a/src/plus/integrations/providers/gitlab/gitlab.ts +++ b/src/plus/integrations/providers/gitlab/gitlab.ts @@ -10,9 +10,9 @@ import { AuthenticationErrorReason, CancellationError, ProviderFetchError, - ProviderRequestClientError, - ProviderRequestNotFoundError, - ProviderRequestRateLimitError, + RequestClientError, + RequestNotFoundError, + RequestRateLimitError, } from '../../../../errors'; import type { Account } from '../../../../git/models/author'; import type { DefaultBranch } from '../../../../git/models/defaultBranch'; @@ -149,7 +149,7 @@ export class GitLabApi implements Disposable { username: user.username || undefined, }; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, provider, scope); } @@ -182,7 +182,7 @@ export class GitLabApi implements Disposable { username: user.username || undefined, }; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, provider, scope); } @@ -242,7 +242,7 @@ export class GitLabApi implements Disposable { name: defaultBranch, }; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, provider, scope); } @@ -362,7 +362,7 @@ export class GitLabApi implements Disposable { return undefined; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, provider, scope); } @@ -516,7 +516,7 @@ export class GitLabApi implements Disposable { pr.mergedAt == null ? undefined : new Date(pr.mergedAt), ); } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, provider, scope); } @@ -565,7 +565,7 @@ export class GitLabApi implements Disposable { return fromGitLabMergeRequestREST(mrs[0], provider, { owner: owner, repo: repo }); } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, provider, scope); } @@ -616,7 +616,7 @@ export class GitLabApi implements Disposable { : undefined, } satisfies RepositoryMetadata; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; throw this.handleException(ex, provider, scope); } @@ -700,7 +700,7 @@ $search: String! return users; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return []; + if (ex instanceof RequestNotFoundError) return []; this.handleException(ex, provider, scope); return []; @@ -771,7 +771,7 @@ $search: String! setLogScopeExit(scope, ` \u2022 projectId=${projectId}`); return projectId; } catch (ex) { - if (ex instanceof ProviderRequestNotFoundError) return undefined; + if (ex instanceof RequestNotFoundError) return undefined; this.handleException(ex, provider, scope); return undefined; @@ -902,7 +902,7 @@ $search: String! case 404: // Not found case 410: // Gone case 422: // Unprocessable Entity - throw new ProviderRequestNotFoundError(ex); + throw new RequestNotFoundError(ex); // case 429: //Too Many Requests case 401: // Unauthorized throw new AuthenticationError('gitlab', AuthenticationErrorReason.Unauthorized, ex); @@ -918,7 +918,7 @@ $search: String! } } - throw new ProviderRequestRateLimitError(ex, token, resetAt); + throw new RequestRateLimitError(ex, token, resetAt); } throw new AuthenticationError('gitlab', AuthenticationErrorReason.Forbidden, ex); case 500: // Internal Server Error @@ -944,7 +944,7 @@ $search: String! } break; default: - if (ex.status >= 400 && ex.status < 500) throw new ProviderRequestClientError(ex); + if (ex.status >= 400 && ex.status < 500) throw new RequestClientError(ex); break; } diff --git a/src/plus/integrations/providers/providersApi.ts b/src/plus/integrations/providers/providersApi.ts index 8d07d04dc2794..33ef73c4f1656 100644 --- a/src/plus/integrations/providers/providersApi.ts +++ b/src/plus/integrations/providers/providersApi.ts @@ -7,8 +7,8 @@ import type { Container } from '../../../container'; import { AuthenticationError, AuthenticationErrorReason, - ProviderRequestClientError, - ProviderRequestRateLimitError, + RequestClientError, + RequestRateLimitError, } from '../../../errors'; import type { PagedResult } from '../../../git/gitProvider'; import type { PullRequest, PullRequestMergeMethod } from '../../../git/models/pullRequest'; @@ -325,9 +325,9 @@ export class ProvidersApi { } } - throw new ProviderRequestRateLimitError(error, token, resetAt); + throw new RequestRateLimitError(error, token, resetAt); } else if (error.response.status >= 400 && error.response.status < 500) { - throw new ProviderRequestClientError(error); + throw new RequestClientError(error); } } throw error;