jam411 3 лет назад
Родитель
Сommit
8f8658c55e

+ 2 - 5
packages/app/src/components/Admin/PluginsExtension/PluginInstallerForm.tsx

@@ -3,9 +3,6 @@ import React, { useCallback } from 'react';
 import { apiv3Post } from '~/client/util/apiv3-client';
 import { toastError, toastSuccess } from '~/client/util/toastr';
 
-import AdminInstallButtonRow from '../Common/AdminUpdateButtonRow';
-// TODO: error notification (toast, loggerFactory)
-// TODO: i18n
 
 export const PluginInstallerForm = (): JSX.Element => {
   // const { t } = useTranslation('admin');
@@ -31,8 +28,8 @@ export const PluginInstallerForm = (): JSX.Element => {
       await apiv3Post('/plugins', { pluginInstallerForm });
       toastSuccess('Plugin Install Successed!');
     }
-    catch (err) {
-      toastError(err);
+    catch (e) {
+      toastError(e);
     }
   }, []);
 

+ 2 - 1
packages/app/src/server/crowi/index.js

@@ -702,7 +702,8 @@ Crowi.prototype.setupPluginService = async function() {
   if (this.pluginService == null) {
     this.pluginService = new PluginService(this);
   }
-  // download the plugins repositories, if document exists but there is no repository
+  // download plugin repositories, if document exists but there is no repository
+  // TODO: Cannot download unless connected to the Internet at setup.
   await this.pluginService.downloadNotExistPluginRepositories();
 };
 

+ 4 - 4
packages/app/src/server/routes/apiv3/plugins.ts

@@ -11,11 +11,11 @@ module.exports = (crowi: Crowi) => {
   const { pluginService } = crowi;
 
   router.post('/', async(req: PluginInstallerFormRequest, res: ApiV3Response) => {
-    if (pluginService == null) {
-      return res.apiv3Err(400);
-    }
-
     try {
+      if (pluginService == null) {
+        throw new Error('pluginService is not set up');
+      }
+
       await pluginService.install(req.body.pluginInstallerForm);
       return res.apiv3({});
     }

+ 37 - 28
packages/app/src/server/service/plugin.ts

@@ -27,7 +27,6 @@ const PLUGINS_STATIC_DIR = '/static/plugins'; // configured by express.static
 
 export type GrowiPluginResourceEntries = [installedPath: string, href: string][];
 
-
 function retrievePluginManifest(growiPlugin: GrowiPlugin): ViteManifest {
   const manifestPath = resolveFromRoot(path.join('tmp/plugins', growiPlugin.installedPath, 'dist/manifest.json'));
   const manifestStr: string = readFileSync(manifestPath, 'utf-8');
@@ -81,35 +80,41 @@ export class PluginService implements IPluginService {
   }
 
   async install(origin: GrowiPluginOrigin): Promise<void> {
+    try {
     // download
-    const ghUrl = new URL(origin.url);
-    const ghPathname = ghUrl.pathname;
-    // TODO: Branch names can be specified.
-    const ghBranch = 'main';
-
-    const match = ghPathname.match(githubReposIdPattern);
-    if (ghUrl.hostname !== 'github.com' || match == null) {
-      throw new Error('The GitHub Repository URL is invalid.');
-    }
+      const ghUrl = new URL(origin.url);
+      const ghPathname = ghUrl.pathname;
+      // TODO: Branch names can be specified.
+      const ghBranch = 'main';
+
+      const match = ghPathname.match(githubReposIdPattern);
+      if (ghUrl.hostname !== 'github.com' || match == null) {
+        throw new Error('The GitHub Repository URL is invalid.');
+      }
 
-    const ghOrganizationName = match[1];
-    const ghReposName = match[2];
-    const installedPath = `${ghOrganizationName}/${ghReposName}`;
+      const ghOrganizationName = match[1];
+      const ghReposName = match[2];
+      const installedPath = `${ghOrganizationName}/${ghReposName}`;
 
-    // download github repository to local file system
-    await this.downloadPluginRepository(ghOrganizationName, ghReposName, ghBranch);
+      // download github repository to local file system
+      await this.downloadPluginRepository(ghOrganizationName, ghReposName, ghBranch);
 
-    // delete old document
-    await this.deleteOldDocument(installedPath);
+      // delete old document
+      await this.deleteOldPluginDocument(installedPath);
 
-    // save plugin metadata
-    const plugins = await PluginService.detectPlugins(origin, installedPath);
-    await this.savePluginMetaData(plugins);
+      // save plugin metadata
+      const plugins = await PluginService.detectPlugins(origin, installedPath);
+      await this.savePluginMetaData(plugins);
+    }
+    catch (err) {
+      logger.error(err);
+      throw err;
+    }
 
     return;
   }
 
-  private async deleteOldDocument(path: string): Promise<void> {
+  private async deleteOldPluginDocument(path: string): Promise<void> {
     const GrowiPlugin = mongoose.model<GrowiPlugin>('GrowiPlugin');
     const growiPlugin = await GrowiPlugin.findOne({ installedPath: path });
     // if document already exists, delete old document before rename path
@@ -123,7 +128,7 @@ export class PluginService implements IPluginService {
     const unzippedPath = path.join(pluginStoringPath, ghOrganizationName);
 
     const downloadFile = async(requestUrl: string, filePath: string) => {
-      return new Promise<void>((resolve, reject) => {
+      return new Promise<void>((resolve, rejects) => {
         axios({
           method: 'GET',
           url: requestUrl,
@@ -139,10 +144,12 @@ export class PluginService implements IPluginService {
                 });
             }
             else {
-              return reject(res.status);
+              rejects(res.status);
             }
-          }).catch((err) => {
-            return reject(err);
+          }).catch((e) => {
+            logger.error(e);
+            // eslint-disable-next-line prefer-promise-reject-errors
+            rejects('Filed to download file.');
           });
       });
     };
@@ -157,7 +164,8 @@ export class PluginService implements IPluginService {
         deleteZipFile(zipFilePath);
       }
       catch (err) {
-        return err;
+        logger.error(err);
+        throw new Error('Filed to unzip.');
       }
     };
 
@@ -169,7 +177,8 @@ export class PluginService implements IPluginService {
         fs.renameSync(oldPath, newPath);
       }
       catch (err) {
-        return err;
+        logger.error(err);
+        throw new Error('Filed to rename path.');
       }
     };
 
@@ -179,7 +188,7 @@ export class PluginService implements IPluginService {
       await renamePath(`${unzippedPath}/${ghReposName}-${ghBranch}`, `${unzippedPath}/${ghReposName}`);
     }
     catch (err) {
-      logger.error(err);
+      throw err;
     }
 
     return;