Prechádzať zdrojové kódy

Merge pull request #7471 from weseek/fix/react-dom-internal-server-error

fix: Internal server error when input wrong tag to markdown
Yuki Takei 3 rokov pred
rodič
commit
4aed1e39a2

+ 1 - 0
packages/app/package.json

@@ -160,6 +160,7 @@
     "react-dnd": "^14.0.5",
     "react-dnd": "^14.0.5",
     "react-dnd-html5-backend": "^14.1.0",
     "react-dnd-html5-backend": "^14.1.0",
     "react-dom": "^18.2.0",
     "react-dom": "^18.2.0",
+    "react-error-boundary": "^3.1.4",
     "react-i18next": "^12.2.0",
     "react-i18next": "^12.2.0",
     "react-image-crop": "^8.3.0",
     "react-image-crop": "^8.3.0",
     "react-markdown": "^8.0.3",
     "react-markdown": "^8.0.3",

+ 20 - 8
packages/app/src/components/Page/RevisionRenderer.tsx

@@ -1,20 +1,30 @@
 import React from 'react';
 import React from 'react';
 
 
+import { ErrorBoundary, FallbackProps } from 'react-error-boundary';
 import ReactMarkdown from 'react-markdown';
 import ReactMarkdown from 'react-markdown';
 
 
 import type { RendererOptions } from '~/services/renderer/renderer';
 import type { RendererOptions } from '~/services/renderer/renderer';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
 
 
-
 const logger = loggerFactory('components:Page:RevisionRenderer');
 const logger = loggerFactory('components:Page:RevisionRenderer');
 
 
-
 type Props = {
 type Props = {
   rendererOptions: RendererOptions,
   rendererOptions: RendererOptions,
   markdown: string,
   markdown: string,
   additionalClassName?: string,
   additionalClassName?: string,
 }
 }
 
 
+const ErrorFallback: React.FC<FallbackProps> = React.memo(({ error, resetErrorBoundary }) => {
+  return (
+    <div role="alert">
+      <p>Something went wrong:</p>
+      <pre>{error.message}</pre>
+      <button onClick={resetErrorBoundary}>Reload</button>
+    </div>
+  );
+});
+ErrorFallback.displayName = 'ErrorFallback';
+
 const RevisionRenderer = React.memo((props: Props): JSX.Element => {
 const RevisionRenderer = React.memo((props: Props): JSX.Element => {
 
 
   const {
   const {
@@ -22,12 +32,14 @@ const RevisionRenderer = React.memo((props: Props): JSX.Element => {
   } = props;
   } = props;
 
 
   return (
   return (
-    <ReactMarkdown
-      {...rendererOptions}
-      className={`wiki ${additionalClassName ?? ''}`}
-    >
-      {markdown}
-    </ReactMarkdown>
+    <ErrorBoundary FallbackComponent={ErrorFallback}>
+      <ReactMarkdown
+        {...rendererOptions}
+        className={`wiki ${additionalClassName ?? ''}`}
+      >
+        {markdown}
+      </ReactMarkdown>
+    </ErrorBoundary>
   );
   );
 
 
 });
 });

+ 7 - 0
yarn.lock

@@ -18146,6 +18146,13 @@ react-dropzone@^11.2.4:
     file-selector "^0.2.2"
     file-selector "^0.2.2"
     prop-types "^15.7.2"
     prop-types "^15.7.2"
 
 
+react-error-boundary@^3.1.4:
+  version "3.1.4"
+  resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.4.tgz#255db92b23197108757a888b01e5b729919abde0"
+  integrity sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==
+  dependencies:
+    "@babel/runtime" "^7.12.5"
+
 react-fast-compare@^3.0.1:
 react-fast-compare@^3.0.1:
   version "3.2.0"
   version "3.2.0"
   resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
   resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"