You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

214 lines
6.4 KiB

  1. import type { Uri } from 'vscode';
  2. import type { Response } from '@env/fetch';
  3. import type { RequiredSubscriptionPlans, Subscription } from './subscription';
  4. import { isSubscriptionPaidPlan } from './subscription';
  5. export class AccessDeniedError extends Error {
  6. public readonly subscription: Subscription;
  7. public readonly required: RequiredSubscriptionPlans | undefined;
  8. constructor(subscription: Subscription, required: RequiredSubscriptionPlans | undefined) {
  9. let message;
  10. if (subscription.account?.verified === false) {
  11. message = 'Email verification required';
  12. } else if (required != null && isSubscriptionPaidPlan(required)) {
  13. message = 'Paid plan required';
  14. } else {
  15. message = 'Plan required';
  16. }
  17. super(message);
  18. this.subscription = subscription;
  19. this.required = required;
  20. Error.captureStackTrace?.(this, AccessDeniedError);
  21. }
  22. }
  23. export class AccountValidationError extends Error {
  24. readonly original?: Error;
  25. readonly statusCode?: number;
  26. readonly statusText?: string;
  27. constructor(message: string, original?: Error, statusCode?: number, statusText?: string) {
  28. message += `; status=${statusCode}: ${statusText}`;
  29. super(message);
  30. this.original = original;
  31. this.statusCode = statusCode;
  32. this.statusText = statusText;
  33. Error.captureStackTrace?.(this, AccountValidationError);
  34. }
  35. }
  36. export const enum AuthenticationErrorReason {
  37. UserDidNotConsent = 1,
  38. Unauthorized = 2,
  39. Forbidden = 3,
  40. }
  41. export class AuthenticationError extends Error {
  42. readonly id: string;
  43. readonly original?: Error;
  44. readonly reason: AuthenticationErrorReason | undefined;
  45. constructor(id: string, reason?: AuthenticationErrorReason, original?: Error);
  46. constructor(id: string, message?: string, original?: Error);
  47. constructor(id: string, messageOrReason: string | AuthenticationErrorReason | undefined, original?: Error) {
  48. let message;
  49. let reason: AuthenticationErrorReason | undefined;
  50. if (messageOrReason == null) {
  51. message = `Unable to get required authentication session for '${id}'`;
  52. } else if (typeof messageOrReason === 'string') {
  53. message = messageOrReason;
  54. reason = undefined;
  55. } else {
  56. reason = messageOrReason;
  57. switch (reason) {
  58. case AuthenticationErrorReason.UserDidNotConsent:
  59. message = `'${id}' authentication is required for this operation`;
  60. break;
  61. case AuthenticationErrorReason.Unauthorized:
  62. message = `Your '${id}' credentials are either invalid or expired`;
  63. break;
  64. case AuthenticationErrorReason.Forbidden:
  65. message = `Your '${id}' credentials do not have the required access`;
  66. break;
  67. }
  68. }
  69. super(message);
  70. this.id = id;
  71. this.original = original;
  72. this.reason = reason;
  73. Error.captureStackTrace?.(this, AuthenticationError);
  74. }
  75. }
  76. export class ExtensionNotFoundError extends Error {
  77. constructor(public readonly extensionId: string, public readonly extensionName: string) {
  78. super(
  79. `Unable to find the ${extensionName} extension (${extensionId}). Please ensure it is installed and enabled.`,
  80. );
  81. Error.captureStackTrace?.(this, ExtensionNotFoundError);
  82. }
  83. }
  84. export const enum OpenVirtualRepositoryErrorReason {
  85. RemoteHubApiNotFound = 1,
  86. NotAGitHubRepository = 2,
  87. GitHubAuthenticationNotFound = 3,
  88. GitHubAuthenticationDenied = 4,
  89. }
  90. export class OpenVirtualRepositoryError extends Error {
  91. readonly original?: Error;
  92. readonly reason: OpenVirtualRepositoryErrorReason | undefined;
  93. readonly repoPath: string;
  94. constructor(repoPath: string, reason?: OpenVirtualRepositoryErrorReason, original?: Error);
  95. constructor(repoPath: string, message?: string, original?: Error);
  96. constructor(
  97. repoPath: string,
  98. messageOrReason: string | OpenVirtualRepositoryErrorReason | undefined,
  99. original?: Error,
  100. ) {
  101. let message;
  102. let reason: OpenVirtualRepositoryErrorReason | undefined;
  103. if (messageOrReason == null) {
  104. message = `Unable to open the virtual repository: ${repoPath}`;
  105. } else if (typeof messageOrReason === 'string') {
  106. message = messageOrReason;
  107. reason = undefined;
  108. } else {
  109. reason = messageOrReason;
  110. message = `Unable to open the virtual repository: ${repoPath}; `;
  111. switch (reason) {
  112. case OpenVirtualRepositoryErrorReason.RemoteHubApiNotFound:
  113. message +=
  114. 'Unable to get required api from the GitHub Repositories extension. Please ensure that the GitHub Repositories extension is installed and enabled';
  115. break;
  116. case OpenVirtualRepositoryErrorReason.NotAGitHubRepository:
  117. message += 'Only GitHub repositories are supported currently';
  118. break;
  119. case OpenVirtualRepositoryErrorReason.GitHubAuthenticationNotFound:
  120. message += 'Unable to get required GitHub authentication';
  121. break;
  122. case OpenVirtualRepositoryErrorReason.GitHubAuthenticationDenied:
  123. message += 'GitHub authentication is required';
  124. break;
  125. }
  126. }
  127. super(message);
  128. this.original = original;
  129. this.reason = reason;
  130. this.repoPath = repoPath;
  131. Error.captureStackTrace?.(this, OpenVirtualRepositoryError);
  132. }
  133. }
  134. export class ProviderFetchError extends Error {
  135. get status() {
  136. return this.response.status;
  137. }
  138. get statusText() {
  139. return this.response.statusText;
  140. }
  141. constructor(provider: string, public readonly response: Response, errors?: { message: string }[]) {
  142. super(
  143. `${provider} request failed: ${!response.ok ? `(${response.status}) ${response.statusText}. ` : ''}${
  144. errors?.length ? errors[0].message : ''
  145. }`,
  146. );
  147. Error.captureStackTrace?.(this, ProviderFetchError);
  148. }
  149. }
  150. export class ProviderNotFoundError extends Error {
  151. constructor(pathOrUri: string | Uri | undefined) {
  152. super(
  153. `No provider registered for '${
  154. pathOrUri == null
  155. ? String(pathOrUri)
  156. : typeof pathOrUri === 'string'
  157. ? pathOrUri
  158. : pathOrUri.toString(true)
  159. }'`,
  160. );
  161. Error.captureStackTrace?.(this, ProviderNotFoundError);
  162. }
  163. }
  164. export class ProviderRequestClientError extends Error {
  165. constructor(public readonly original: Error) {
  166. super(original.message);
  167. Error.captureStackTrace?.(this, ProviderRequestClientError);
  168. }
  169. }
  170. export class ProviderRequestNotFoundError extends Error {
  171. constructor(public readonly original: Error) {
  172. super(original.message);
  173. Error.captureStackTrace?.(this, ProviderRequestNotFoundError);
  174. }
  175. }
  176. export class ProviderRequestRateLimitError extends Error {
  177. constructor(
  178. public readonly original: Error,
  179. public readonly token: string,
  180. public readonly resetAt: number | undefined,
  181. ) {
  182. super(original.message);
  183. Error.captureStackTrace?.(this, ProviderRequestRateLimitError);
  184. }
  185. }