diff --git a/apps/web/package.json b/apps/web/package.json index 0160eff7..e74b9878 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -55,6 +55,7 @@ "react": "19.1.0", "react-blurhash": "0.3.0", "react-dom": "19.1.0", + "react-error-boundary": "6.0.0", "react-freeze": "1.0.4", "react-i18next": "15.5.3", "react-image-gallery": "1.4.0", diff --git a/apps/web/src/modules/gallery/PhotoMasonryItem.tsx b/apps/web/src/modules/gallery/PhotoMasonryItem.tsx index dcee8257..e283212d 100644 --- a/apps/web/src/modules/gallery/PhotoMasonryItem.tsx +++ b/apps/web/src/modules/gallery/PhotoMasonryItem.tsx @@ -2,6 +2,7 @@ import clsx from 'clsx' import { m } from 'motion/react' import { Fragment, useCallback, useEffect, useRef, useState } from 'react' import { Blurhash } from 'react-blurhash' +import { ErrorBoundary } from 'react-error-boundary' import { useTranslation } from 'react-i18next' import { @@ -229,15 +230,17 @@ export const PhotoMasonryItem = ({ > {/* Blurhash 占位符 */} {data.blurhash && ( - + null}> + + )} {!imageError && ( diff --git a/apps/web/src/pages/(debug)/blurhash.tsx b/apps/web/src/pages/(debug)/blurhash.tsx index 52a80037..a66751dd 100644 --- a/apps/web/src/pages/(debug)/blurhash.tsx +++ b/apps/web/src/pages/(debug)/blurhash.tsx @@ -1,5 +1,6 @@ import { photoLoader } from '@afilmory/data' import { Blurhash } from 'react-blurhash' +import { ErrorBoundary } from 'react-error-boundary' export const Component = () => { const photos = photoLoader.getPhotos() @@ -21,16 +22,18 @@ export const Component = () => { width={photo.width} className="absolute inset-0" /> -
- -
+ null}> +
+ +
+
))} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 763d65b6..16166351 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -281,6 +281,9 @@ importers: react-dom: specifier: 19.1.0 version: 19.1.0(react@19.1.0) + react-error-boundary: + specifier: 6.0.0 + version: 6.0.0(react@19.1.0) react-freeze: specifier: 1.0.4 version: 1.0.4(react@19.1.0) @@ -1960,7 +1963,7 @@ packages: resolution: {integrity: sha512-fyjAACV62oPV925xFCrH8DR5xWhg9KYtJT4s3u54jxp+L/hbpTY2kIeEFFbFe+a/HCE94zGQMZLIpVTPVZDhaA==} peerDependencies: '@types/react': '*' - react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react: 18.3.1 peerDependenciesMeta: '@types/react': optional: true @@ -6687,6 +6690,11 @@ packages: peerDependencies: react: '>=16.13.1' + react-error-boundary@6.0.0: + resolution: {integrity: sha512-gdlJjD7NWr0IfkPlaREN2d9uUZUlksrfOx7SX62VRerwXbMY6ftGCIZua1VG1aXFNOimhISsTq+Owp725b9SiA==} + peerDependencies: + react: '>=16.13.1' + react-fast-compare@3.2.2: resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} @@ -15457,6 +15465,11 @@ snapshots: '@babel/runtime': 7.27.6 react: 19.1.0 + react-error-boundary@6.0.0(react@19.1.0): + dependencies: + '@babel/runtime': 7.27.6 + react: 19.1.0 + react-fast-compare@3.2.2: {} react-freeze@1.0.4(react@19.1.0):