itizawa 5 years ago
parent
commit
3b4d78fb16

+ 7 - 4
src/client/js/components/PageDuplicateModal.jsx

@@ -25,6 +25,7 @@ const PageDuplicateModal = (props) => {
 
   const [pageNameInput, setPageNameInput] = useState(path);
   const [errorCode, setErrorCode] = useState(null);
+  const [errorMessage, setErrorMessage] = useState(null);
 
   /**
    * change pageNameInput
@@ -37,12 +38,14 @@ const PageDuplicateModal = (props) => {
   async function clickDuplicateButtonHandler() {
     try {
       setErrorCode(null);
+      setErrorMessage(null);
       const res = await appContainer.apiPost('/pages.duplicate', { page_id: pageId, new_path: pageNameInput });
       const { page } = res;
-      window.location.href = encodeURI(urljoin(page.path, '?duplicated=', path));
+      window.location.href = encodeURI(`${page.path}'?duplicated='${path}`);
     }
     catch (err) {
-      setErrorCode(err.message);
+      setErrorCode(err.code);
+      setErrorMessage(err.message);
     }
   }
 
@@ -63,7 +66,7 @@ const PageDuplicateModal = (props) => {
             <div className="input-group-prepend">
               <span className="input-group-text">{crowi.url}</span>
             </div>
-            {!isReachable
+            {isReachable
               // GW-2355 refactor typeahead
               ? <PagePathAutoComplete crowi={appContainer} initializedPath={path} addTrailingSlash />
               : (
@@ -79,7 +82,7 @@ const PageDuplicateModal = (props) => {
         </div>
       </ModalBody>
       <ModalFooter>
-        <ApiErrorMessage errorCode={errorCode} linkPath={path} />
+        <ApiErrorMessage errorCode={errorCode} errorMessage={errorMessage} linkPath={path} />
         <button type="button" className="btn btn-primary" onClick={clickDuplicateButtonHandler}>Duplicate page</button>
       </ModalFooter>
     </Modal>

+ 29 - 12
src/client/js/components/PageManagement/ApiErrorMessage.jsx

@@ -4,27 +4,42 @@ import PropTypes from 'prop-types';
 import { withTranslation } from 'react-i18next';
 
 const ApiErrorMessage = (props) => {
-  const { t, errorCode, linkPath } = props;
+  const {
+    t, errorCode, errorMessage, linkPath,
+  } = props;
 
-  function renderMessage() {
+  function renderMessageByErrorCode() {
     switch (errorCode) {
       case 'already_exists':
         return (
-          <span className="text-danger">
+          <>
             <strong><i className="icon-fw icon-ban"></i>{ t('page_api_error.already_exists') }</strong>
             <small><a href={linkPath}>{linkPath} <i className="icon-login"></i></a></small>
-          </span>
+          </>
         );
       default:
         return null;
     }
   }
 
-  return (
-    <>
-      {renderMessage()}
-    </>
-  );
+  if (errorCode != null) {
+    return (
+      <span className="text-danger">
+        {renderMessageByErrorCode()}
+      </span>
+    );
+  }
+
+  if (errorMessage != null) {
+    return (
+      <span className="text-danger">
+        {errorMessage}
+      </span>
+    );
+  }
+
+  // render null if no error has occurred
+  return null;
 
   // TODO GW-79 Set according to error message
   // <div>
@@ -51,9 +66,11 @@ const ApiErrorMessage = (props) => {
 };
 
 ApiErrorMessage.propTypes = {
-  t: PropTypes.func.isRequired, //  i18next
-  errorCode: PropTypes.string,
-  linkPath: PropTypes.string,
+  t:            PropTypes.func.isRequired, //  i18next
+
+  errorCode:    PropTypes.string,
+  errorMessage: PropTypes.string,
+  linkPath:     PropTypes.string,
 };
 
 export default withTranslation()(ApiErrorMessage);

+ 5 - 2
src/client/js/services/AppContainer.js

@@ -8,6 +8,8 @@ import InterceptorManager from '@commons/service/interceptor-manager';
 import emojiStrategy from '../util/emojione/emoji_strategy_shrinked.json';
 import GrowiRenderer from '../util/GrowiRenderer';
 
+import Apiv1ErrorHandler from '../util/apiv1ErrorHandler';
+
 import {
   DetachCodeBlockInterceptor,
   RestoreCodeBlockInterceptor,
@@ -430,8 +432,9 @@ export default class AppContainer extends Container {
     }
 
     // Return error code if code is exist
-    if (res.data.code) {
-      throw new Error(res.data.code);
+    if (res.data.code != null) {
+      const error = new Apiv1ErrorHandler(res.data.error, res.data.code);
+      throw error;
     }
 
     throw new Error(res.data.error);

+ 12 - 0
src/client/js/util/apiv1ErrorHandler.js

@@ -0,0 +1,12 @@
+class Apiv1ErrorHandler extends Error {
+
+  constructor(message = '', code = '') {
+    super();
+
+    this.message = message;
+    this.code = code;
+  }
+
+}
+
+module.exports = Apiv1ErrorHandler;