index.ts 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. import { HttpStatusCode } from "axios";
  2. export interface ApiErrorResponse {
  3. code: string;
  4. message: string;
  5. }
  6. export class ApiError extends Error {
  7. httpStatusCode: number;
  8. errCode: string;
  9. constructor(message: string, errCode: string, httpStatus: number) {
  10. super(message);
  11. this.name = "ApiError";
  12. this.errCode = errCode;
  13. this.httpStatusCode = httpStatus;
  14. }
  15. }
  16. export function isApiErrorResponse(object: any): object is ApiErrorResponse {
  17. return object && "code" in object && "message" in object;
  18. }
  19. export const CustomError = {
  20. THUMBNAIL_GENERATION_FAILED: "thumbnail generation failed",
  21. VIDEO_PLAYBACK_FAILED: "video playback failed",
  22. ETAG_MISSING: "no header/etag present in response body",
  23. KEY_MISSING: "encrypted key missing from localStorage",
  24. FAILED_TO_LOAD_WEB_WORKER: "failed to load web worker",
  25. CHUNK_MORE_THAN_EXPECTED: "chunks more than expected",
  26. CHUNK_LESS_THAN_EXPECTED: "chunks less than expected",
  27. UNSUPPORTED_FILE_FORMAT: "unsupported file format",
  28. FILE_TOO_LARGE: "file too large",
  29. SUBSCRIPTION_EXPIRED: "subscription expired",
  30. STORAGE_QUOTA_EXCEEDED: "storage quota exceeded",
  31. SESSION_EXPIRED: "session expired",
  32. INVALID_MIME_TYPE: (type: string) => `invalid mime type -${type}`,
  33. SIGNUP_FAILED: "signup failed",
  34. FAV_COLLECTION_MISSING: "favorite collection missing",
  35. INVALID_COLLECTION_OPERATION: "invalid collection operation",
  36. TO_MOVE_FILES_FROM_MULTIPLE_COLLECTIONS:
  37. "to move files from multiple collections",
  38. REQUEST_CANCELLED: "request canceled",
  39. REQUEST_FAILED: "request failed",
  40. TOKEN_EXPIRED: "token expired",
  41. TOKEN_MISSING: "token missing",
  42. TOO_MANY_REQUESTS: "too many requests",
  43. BAD_REQUEST: "bad request",
  44. SUBSCRIPTION_NEEDED: "subscription not present",
  45. NOT_FOUND: "not found ",
  46. NO_METADATA: "no metadata",
  47. TOO_LARGE_LIVE_PHOTO_ASSETS: "too large live photo assets",
  48. NOT_A_DATE: "not a date",
  49. NOT_A_LOCATION: "not a location",
  50. FILE_ID_NOT_FOUND: "file with id not found",
  51. WEAK_DEVICE: "password decryption failed on the device",
  52. INCORRECT_PASSWORD: "incorrect password",
  53. UPLOAD_CANCELLED: "upload cancelled",
  54. REQUEST_TIMEOUT: "request taking too long",
  55. HIDDEN_COLLECTION_SYNC_FILE_ATTEMPTED:
  56. "hidden collection sync file attempted",
  57. UNKNOWN_ERROR: "Something went wrong, please try again",
  58. TYPE_DETECTION_FAILED: (fileFormat: string) =>
  59. `type detection failed ${fileFormat}`,
  60. WINDOWS_NATIVE_IMAGE_PROCESSING_NOT_SUPPORTED:
  61. "Windows native image processing is not supported",
  62. NETWORK_ERROR: "Network Error",
  63. NOT_FILE_OWNER: "not file owner",
  64. UPDATE_EXPORTED_RECORD_FAILED: "update file exported record failed",
  65. EXPORT_STOPPED: "export stopped",
  66. NO_EXPORT_FOLDER_SELECTED: "no export folder selected",
  67. EXPORT_FOLDER_DOES_NOT_EXIST: "export folder does not exist",
  68. AUTH_KEY_NOT_FOUND: "auth key not found",
  69. EXIF_DATA_NOT_FOUND: "exif data not found",
  70. SELECT_FOLDER_ABORTED: "select folder aborted",
  71. NON_MEDIA_FILE: "non media file",
  72. NOT_AVAILABLE_ON_WEB: "not available on web",
  73. UNSUPPORTED_RAW_FORMAT: "unsupported raw format",
  74. NON_PREVIEWABLE_FILE: "non previewable file",
  75. PROCESSING_FAILED: "processing failed",
  76. EXPORT_RECORD_JSON_PARSING_FAILED: "export record json parsing failed",
  77. TWO_FACTOR_ENABLED: "two factor enabled",
  78. PASSKEYS_TWO_FACTOR_ENABLED: "passkeys two factor enabled",
  79. CLIENT_ERROR: "client error",
  80. ServerError: "server error",
  81. FILE_NOT_FOUND: "file not found",
  82. UNSUPPORTED_PLATFORM: "Unsupported platform",
  83. MODEL_DOWNLOAD_PENDING:
  84. "Model download pending, skipping clip search request",
  85. DOWNLOAD_MANAGER_NOT_READY: "Download manager not initialized",
  86. UPDATE_URL_FILE_ID_MISMATCH: "update url file id mismatch",
  87. URL_ALREADY_SET: "url already set",
  88. FILE_CONVERSION_FAILED: "file conversion failed",
  89. };
  90. export function handleUploadError(error: any): Error {
  91. const parsedError = parseUploadErrorCodes(error);
  92. // breaking errors
  93. switch (parsedError.message) {
  94. case CustomError.SUBSCRIPTION_EXPIRED:
  95. case CustomError.STORAGE_QUOTA_EXCEEDED:
  96. case CustomError.SESSION_EXPIRED:
  97. case CustomError.UPLOAD_CANCELLED:
  98. throw parsedError;
  99. }
  100. return parsedError;
  101. }
  102. export function parseUploadErrorCodes(error: any) {
  103. let parsedMessage = null;
  104. if (error instanceof ApiError) {
  105. switch (error.httpStatusCode) {
  106. case HttpStatusCode.PaymentRequired:
  107. parsedMessage = CustomError.SUBSCRIPTION_EXPIRED;
  108. break;
  109. case HttpStatusCode.UpgradeRequired:
  110. parsedMessage = CustomError.STORAGE_QUOTA_EXCEEDED;
  111. break;
  112. case HttpStatusCode.Unauthorized:
  113. parsedMessage = CustomError.SESSION_EXPIRED;
  114. break;
  115. case HttpStatusCode.PayloadTooLarge:
  116. parsedMessage = CustomError.FILE_TOO_LARGE;
  117. break;
  118. default:
  119. parsedMessage = `${CustomError.UNKNOWN_ERROR} statusCode:${error.httpStatusCode}`;
  120. }
  121. } else {
  122. parsedMessage = error.message;
  123. }
  124. return new Error(parsedMessage);
  125. }
  126. export const parseSharingErrorCodes = (error: any) => {
  127. let parsedMessage = null;
  128. if (error instanceof ApiError) {
  129. switch (error.httpStatusCode) {
  130. case HttpStatusCode.BadRequest:
  131. parsedMessage = CustomError.BAD_REQUEST;
  132. break;
  133. case HttpStatusCode.PaymentRequired:
  134. parsedMessage = CustomError.SUBSCRIPTION_NEEDED;
  135. break;
  136. case HttpStatusCode.NotFound:
  137. parsedMessage = CustomError.NOT_FOUND;
  138. break;
  139. case HttpStatusCode.Unauthorized:
  140. case HttpStatusCode.Gone:
  141. parsedMessage = CustomError.TOKEN_EXPIRED;
  142. break;
  143. case HttpStatusCode.TooManyRequests:
  144. parsedMessage = CustomError.TOO_MANY_REQUESTS;
  145. break;
  146. default:
  147. parsedMessage = `${CustomError.UNKNOWN_ERROR} statusCode:${error.httpStatusCode}`;
  148. }
  149. } else {
  150. parsedMessage = error.message;
  151. }
  152. return new Error(parsedMessage);
  153. };