index.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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. PROCESSING_FAILED: "processing failed",
  73. EXPORT_RECORD_JSON_PARSING_FAILED: "export record json parsing failed",
  74. TWO_FACTOR_ENABLED: "two factor enabled",
  75. PASSKEYS_TWO_FACTOR_ENABLED: "passkeys two factor enabled",
  76. CLIENT_ERROR: "client error",
  77. ServerError: "server error",
  78. FILE_NOT_FOUND: "file not found",
  79. UNSUPPORTED_PLATFORM: "Unsupported platform",
  80. UPDATE_URL_FILE_ID_MISMATCH: "update url file id mismatch",
  81. URL_ALREADY_SET: "url already set",
  82. FILE_CONVERSION_FAILED: "file conversion failed",
  83. };
  84. export function handleUploadError(error: any): Error {
  85. const parsedError = parseUploadErrorCodes(error);
  86. // breaking errors
  87. switch (parsedError.message) {
  88. case CustomError.SUBSCRIPTION_EXPIRED:
  89. case CustomError.STORAGE_QUOTA_EXCEEDED:
  90. case CustomError.SESSION_EXPIRED:
  91. case CustomError.UPLOAD_CANCELLED:
  92. throw parsedError;
  93. }
  94. return parsedError;
  95. }
  96. export function parseUploadErrorCodes(error: any) {
  97. let parsedMessage = null;
  98. if (error instanceof ApiError) {
  99. switch (error.httpStatusCode) {
  100. case HttpStatusCode.PaymentRequired:
  101. parsedMessage = CustomError.SUBSCRIPTION_EXPIRED;
  102. break;
  103. case HttpStatusCode.UpgradeRequired:
  104. parsedMessage = CustomError.STORAGE_QUOTA_EXCEEDED;
  105. break;
  106. case HttpStatusCode.Unauthorized:
  107. parsedMessage = CustomError.SESSION_EXPIRED;
  108. break;
  109. case HttpStatusCode.PayloadTooLarge:
  110. parsedMessage = CustomError.FILE_TOO_LARGE;
  111. break;
  112. default:
  113. parsedMessage = `${CustomError.UNKNOWN_ERROR} statusCode:${error.httpStatusCode}`;
  114. }
  115. } else {
  116. parsedMessage = error.message;
  117. }
  118. return new Error(parsedMessage);
  119. }
  120. export const parseSharingErrorCodes = (error: any) => {
  121. let parsedMessage = null;
  122. if (error instanceof ApiError) {
  123. switch (error.httpStatusCode) {
  124. case HttpStatusCode.BadRequest:
  125. parsedMessage = CustomError.BAD_REQUEST;
  126. break;
  127. case HttpStatusCode.PaymentRequired:
  128. parsedMessage = CustomError.SUBSCRIPTION_NEEDED;
  129. break;
  130. case HttpStatusCode.NotFound:
  131. parsedMessage = CustomError.NOT_FOUND;
  132. break;
  133. case HttpStatusCode.Unauthorized:
  134. case HttpStatusCode.Gone:
  135. parsedMessage = CustomError.TOKEN_EXPIRED;
  136. break;
  137. case HttpStatusCode.TooManyRequests:
  138. parsedMessage = CustomError.TOO_MANY_REQUESTS;
  139. break;
  140. default:
  141. parsedMessage = `${CustomError.UNKNOWN_ERROR} statusCode:${error.httpStatusCode}`;
  142. }
  143. } else {
  144. parsedMessage = error.message;
  145. }
  146. return new Error(parsedMessage);
  147. };