fix: 修复ErrorBoundary,使用react-error-boundary (#510)

<!-- Note -->
<!-- This is a template for submitting a new feature.
Use the bug fix template if you're submitting a bug fix pull request by adding `template=bug_fix.md` to your pull request URL. -->

# Description
<!-- Describe the new feature or modification to an existing feature clearly and consciously. -->

# Motivation
<!-- Explain the reason for adding or modifying this feature. -->

# Key changes
<!-- Provide a technically detailed description of the key changes made. -->
- Frontend
- Backend

# Test plan
## Suggestions
<!-- Provide any suggestions or recommendations for improvements in the testing plan. -->

## Underlying risk
<!-- Identify any potential risks or issues that may arise from the new feature or modification. -->

# Showcase
<!-- Including any screenshots of the new feature or modification. -->

Reviewed-on: daoyoucloud/tachycode#510
Reviewed-by: sealday <zhanglin@daoyoucloud.com>
Co-authored-by: bai.jingfeng <bai.jingfeng@foxmail.com>
Co-committed-by: bai.jingfeng <bai.jingfeng@foxmail.com>
This commit is contained in:
bai.jingfeng 2024-03-27 14:36:26 +08:00 committed by sealday
parent b0cd02ee34
commit 0eeb44c306
6 changed files with 14 additions and 34 deletions

View File

@ -1,11 +1,12 @@
import { SchemaComponent } from '@nocobase/client'; import { SchemaComponent } from '@nocobase/client';
import React from 'react'; import React from 'react';
import { ErrorBoundary } from './ErrorBoundary'; import { ErrorBoundary } from 'react-error-boundary';
import { ErrorBoundaryFallBack } from './ErrorBoundary';
export const CustomAssociatedField = (props) => { export const CustomAssociatedField = (props) => {
if (!props.component) return; if (!props.component) return;
return ( return (
<ErrorBoundary> <ErrorBoundary fallback={<ErrorBoundaryFallBack />}>
<SchemaComponent <SchemaComponent
schema={{ schema={{
type: 'string', type: 'string',

View File

@ -1,11 +1,12 @@
import { SchemaComponent, SchemaSettings, useApp, useDesignable, usePlugin } from '@nocobase/client'; import { SchemaComponent, SchemaSettings, useApp, useDesignable, usePlugin } from '@nocobase/client';
import React from 'react'; import React from 'react';
import { ErrorBoundary } from 'react-error-boundary';
import { useTranslation } from '../../locale'; import { useTranslation } from '../../locale';
import { useField, useFieldSchema } from '@formily/react'; import { useField, useFieldSchema } from '@formily/react';
import { Field } from '@nocobase/database'; import { Field } from '@nocobase/database';
import { useCustomComponent } from '../../hooks/useCustomComponent'; import { useCustomComponent } from '../../hooks/useCustomComponent';
import { CustomComponentType } from './custom-components'; import { CustomComponentType } from './custom-components';
import { ErrorBoundary } from './ErrorBoundary'; import { ErrorBoundaryFallBack } from './ErrorBoundary';
export const CustomComponentStub = (props) => { export const CustomComponentStub = (props) => {
return <div></div>; return <div></div>;
@ -14,7 +15,7 @@ export const CustomComponentStub = (props) => {
export const CustomComponentDispatcher = (props) => { export const CustomComponentDispatcher = (props) => {
if (!props.component) return; if (!props.component) return;
return ( return (
<ErrorBoundary> <ErrorBoundary fallback={<ErrorBoundaryFallBack />}>
<SchemaComponent <SchemaComponent
schema={{ schema={{
type: 'void', type: 'void',

View File

@ -1,11 +1,12 @@
import { SchemaComponent } from '@nocobase/client'; import { SchemaComponent } from '@nocobase/client';
import React from 'react'; import React from 'react';
import { ErrorBoundary } from './ErrorBoundary'; import { ErrorBoundary } from 'react-error-boundary';
import { ErrorBoundaryFallBack } from './ErrorBoundary';
export const CustomField = (props) => { export const CustomField = (props) => {
if (!props.component) return; if (!props.component) return;
return ( return (
<ErrorBoundary> <ErrorBoundary fallback={<ErrorBoundaryFallBack />}>
<SchemaComponent <SchemaComponent
schema={{ schema={{
type: 'string', type: 'string',

View File

@ -1,31 +1,8 @@
import React, { useState, useEffect } from 'react'; import React from 'react';
import { useTranslation } from '../../locale'; import { useTranslation } from '../../locale';
export const ErrorBoundary = ({ children, fallback = null }) => { export const ErrorBoundaryFallBack = () => {
const { t } = useTranslation(); const { t } = useTranslation();
const [hasError, setHasError] = useState(false);
useEffect(() => {
// 捕获子组件的错误
const handleError = (error) => {
console.error('Error caught by ErrorBoundary:', error);
setHasError(true);
};
// TODO: 或者上报至错误服务器,记录
// 添加错误处理函数到 window
window.addEventListener('error', handleError);
// 移除事件监听器
return () => {
window.removeEventListener('error', handleError);
};
}, []);
// 如果有错误,展示备用, 可以通过fallback回调自定义,或者显示默认 UI 组件 // 如果有错误,展示备用, 可以通过fallback回调自定义,或者显示默认 UI 组件
if (hasError) { return <div>{t('Something went wrong. Please contact the developer to resolve the issue.')}</div>;
return fallback ? fallback : <div>{t('Something went wrong. Please try again later.')}</div>;
}
// 否则渲染子组件
return children;
}; };

View File

@ -19,5 +19,5 @@
"Please select": "Please select", "Please select": "Please select",
"Association field": "Association field", "Association field": "Association field",
"HomePage Config": "HomePage Config", "HomePage Config": "HomePage Config",
"Something went wrong. Please try again later.": "Something went wrong. Please try again later." "Something went wrong. Please contact the developer to resolve the issue.": "Something went wrong. Please contact the developer to resolve the issue."
} }

View File

@ -19,5 +19,5 @@
"Please select": "请选择", "Please select": "请选择",
"Association field": "关联字段", "Association field": "关联字段",
"HomePage Config": "主页配置", "HomePage Config": "主页配置",
"Something went wrong. Please try again later.": "系统内部显示错误,请稍后再试" "Something went wrong. Please contact the developer to resolve the issue.": "系统内部错误,请联系开发者解决"
} }