Explorar el Código

feat: show error details as toast on g2g failure

https://redmine.weseek.co.jp/issues/106571
mizozobu hace 3 años
padre
commit
991d8a4a4a

+ 3 - 5
packages/app/src/components/Admin/G2GDataTransfer.tsx

@@ -4,10 +4,8 @@ import { useTranslation } from 'react-i18next';
 
 import { useGenerateTransferKeyWithThrottle } from '~/client/services/g2g-transfer';
 import { toastError } from '~/client/util/apiNotification';
-import { apiv3Get } from '~/client/util/apiv3-client';
+import { apiv3Get, apiv3Post } from '~/client/util/apiv3-client';
 import { useAdminSocket } from '~/stores/socket-io';
-import customAxios from '~/utils/axios';
-
 
 import CustomCopyToClipBoard from '../Common/CustomCopyToClipBoard';
 
@@ -94,14 +92,14 @@ const G2GDataTransfer = (): JSX.Element => {
     e.preventDefault();
 
     try {
-      await customAxios.post('/_api/v3/g2g-transfer/transfer', {
+      await apiv3Post('/g2g-transfer/transfer', {
         transferKey: startTransferKey,
         collections: Array.from(selectedCollections),
         optionsMap,
       });
     }
     catch (errs) {
-      toastError('Failed to transfer');
+      toastError(errs);
     }
   }, [startTransferKey, selectedCollections, optionsMap]);
 

+ 3 - 3
packages/app/src/server/routes/apiv3/g2g-transfer.ts

@@ -379,10 +379,10 @@ module.exports = (crowi: Crowi): Router => {
     }
 
     // Check if can transfer
-    const canTransfer = await g2gTransferPusherService.canTransfer(toGROWIInfo);
-    if (!canTransfer) {
+    const transferability = await g2gTransferPusherService.getTransferability(toGROWIInfo);
+    if (!transferability.canTransfer) {
       logger.debug('Could not transfer.');
-      return res.apiv3Err(new ErrorV3('GROWI is incompatible to transfer data.', 'growi_incompatible_to_transfer'));
+      return res.apiv3Err(new ErrorV3(transferability.reason, 'growi_incompatible_to_transfer'));
     }
 
     // Start transfer

+ 27 - 9
packages/app/src/server/service/g2g-transfer.ts

@@ -47,6 +47,11 @@ export type IDataGROWIInfo = {
   };
 }
 
+/**
+ * Return type for {@link Pusher.getTransferability}
+ */
+type IGetTransferabilityReturn = { canTransfer: true; } | { canTransfer: false; reason: string; };
+
 interface Pusher {
   /**
    * Send to-growi a request to get growi info
@@ -57,7 +62,7 @@ interface Pusher {
    * Check if transfering is proceedable
    * @param {IDataGROWIInfo} fromGROWIInfo
    */
-  canTransfer(fromGROWIInfo: IDataGROWIInfo): Promise<boolean>
+  getTransferability(fromGROWIInfo: IDataGROWIInfo): Promise<IGetTransferabilityReturn>
   /**
    * Transfer all Attachment data to destination GROWI
    * @param {TransferKey} tk Transfer key
@@ -215,33 +220,46 @@ export class G2GTransferPusherService implements Pusher {
   }
 
   /**
-   * Returns whether g2g transfer is possible
+   * Returns whether g2g transfer is possible and reason for failure
    * @param toGROWIInfo to-growi info
-   * @returns Whether g2g transfer is possible
+   * @returns Whether g2g transfer is possible and reason for failure
    */
-  public async canTransfer(toGROWIInfo: IDataGROWIInfo): Promise<boolean> {
+  public async getTransferability(toGROWIInfo: IDataGROWIInfo): Promise<IGetTransferabilityReturn> {
     const { configManager, fileUploadService } = this.crowi;
 
     const version = this.crowi.version;
     if (version !== toGROWIInfo.version) {
-      return false;
+      return {
+        canTransfer: false,
+        reason: `Growi versions mismatch. From: ${version}, To: ${toGROWIInfo.version}.`,
+      };
     }
 
     const userUpperLimit = configManager.getConfig('crowi', 'security:userUpperLimit');
     if ((userUpperLimit ?? Infinity) < (toGROWIInfo.userUpperLimit ?? 0)) {
-      return false;
+      return {
+        canTransfer: false,
+        reason: `From-Growi's user limit exceeds To-Growi's user limit. From: ${userUpperLimit}, To: ${toGROWIInfo.userUpperLimit}.`,
+      };
     }
 
     if (toGROWIInfo.fileUploadDisabled) {
-      return false;
+      return {
+        canTransfer: false,
+        reason: 'File upload is disabled.',
+      };
     }
 
     const totalFileSize = await fileUploadService.getTotalFileSize();
     if ((toGROWIInfo.fileUploadTotalLimit ?? Infinity) < totalFileSize) {
-      return false;
+      return {
+        canTransfer: false,
+        // eslint-disable-next-line max-len, @typescript-eslint/no-non-null-assertion
+        reason: `Total file size exceeds Growi file upload limit. Requires ${totalFileSize.toLocaleString()} bytes, but got ${toGROWIInfo.fileUploadTotalLimit!.toLocaleString()} bytes.`,
+      };
     }
 
-    return true;
+    return { canTransfer: true };
   }
 
   public async transferAttachments(tk: TransferKey): Promise<void> {