@arcblock/ux 2.11.9 → 2.11.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/ErrorBoundary/fallback.d.ts +1 -5
- package/lib/ErrorBoundary/fallback.js +51 -29
- package/lib/Util/index.d.ts +1 -0
- package/lib/Util/index.js +21 -1
- package/package.json +6 -5
- package/src/ErrorBoundary/fallback.tsx +50 -29
- package/src/Util/index.ts +24 -0
@@ -1,8 +1,3 @@
|
|
1
|
-
export interface InternalErrorFallbackProps {
|
2
|
-
title?: string;
|
3
|
-
desc: string;
|
4
|
-
retryFunc?: (() => void) | null;
|
5
|
-
}
|
6
1
|
export interface ErrorFallbackProps {
|
7
2
|
error: Error;
|
8
3
|
}
|
@@ -12,3 +7,4 @@ export interface ErrorFallbackRetryProps {
|
|
12
7
|
resetErrorBoundary: () => void;
|
13
8
|
}
|
14
9
|
export declare function ErrorFallbackRetry({ error, resetErrorBoundary }: ErrorFallbackRetryProps): import("react/jsx-runtime").JSX.Element;
|
10
|
+
export declare function ReactRouterErrorFallback(): import("react/jsx-runtime").JSX.Element;
|
@@ -1,24 +1,48 @@
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
2
|
-
import {
|
2
|
+
import { Alert, AlertTitle, Box, Typography } from '@mui/material';
|
3
|
+
import { useRouteError } from 'react-router-dom';
|
3
4
|
import Button from '../Button';
|
4
|
-
import { styled } from '../Theme';
|
5
5
|
function InternalErrorFallback({
|
6
6
|
title = 'Something went wrong...',
|
7
7
|
desc,
|
8
|
-
|
8
|
+
extraContent = null,
|
9
|
+
severity = 'error'
|
9
10
|
}) {
|
10
|
-
|
11
|
-
|
12
|
-
|
11
|
+
const gotoHome = () => window.location.replace('/');
|
12
|
+
const refresh = () => window.location.reload();
|
13
|
+
return /*#__PURE__*/_jsxs(Alert, {
|
14
|
+
severity: severity,
|
15
|
+
variant: "outlined",
|
16
|
+
icon: false,
|
17
|
+
sx: {
|
18
|
+
justifyContent: 'center'
|
19
|
+
},
|
20
|
+
children: [title ? /*#__PURE__*/_jsx(AlertTitle, {
|
13
21
|
children: title
|
14
|
-
}), /*#__PURE__*/_jsx(
|
22
|
+
}) : null, desc ? /*#__PURE__*/_jsx(Typography, {
|
23
|
+
variant: "body2",
|
24
|
+
mb: 1,
|
15
25
|
children: desc
|
16
|
-
}),
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
26
|
+
}) : null, extraContent ?? /*#__PURE__*/_jsxs(Box, {
|
27
|
+
sx: {
|
28
|
+
display: 'flex',
|
29
|
+
gap: 1,
|
30
|
+
justifyContent: 'center',
|
31
|
+
alignItems: 'center'
|
32
|
+
},
|
33
|
+
children: [/*#__PURE__*/_jsx(Button, {
|
34
|
+
variant: "outlined",
|
35
|
+
color: severity,
|
36
|
+
size: "small",
|
37
|
+
onClick: gotoHome,
|
38
|
+
children: "Home"
|
39
|
+
}), /*#__PURE__*/_jsx(Button, {
|
40
|
+
variant: "contained",
|
41
|
+
color: severity,
|
42
|
+
size: "small",
|
43
|
+
onClick: refresh,
|
44
|
+
children: "Refresh"
|
45
|
+
})]
|
22
46
|
})]
|
23
47
|
});
|
24
48
|
}
|
@@ -35,21 +59,19 @@ export function ErrorFallbackRetry({
|
|
35
59
|
}) {
|
36
60
|
return /*#__PURE__*/_jsx(InternalErrorFallback, {
|
37
61
|
desc: error.message,
|
38
|
-
|
62
|
+
extraContent: /*#__PURE__*/_jsx(Button, {
|
63
|
+
variant: "contained",
|
64
|
+
color: "error",
|
65
|
+
size: "small",
|
66
|
+
onClick: resetErrorBoundary,
|
67
|
+
children: "Try again"
|
68
|
+
})
|
39
69
|
});
|
40
70
|
}
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
h3 {
|
49
|
-
margin: 0;
|
50
|
-
font-size: 16px;
|
51
|
-
}
|
52
|
-
pre {
|
53
|
-
white-space: normal;
|
54
|
-
}
|
55
|
-
`;
|
71
|
+
export function ReactRouterErrorFallback() {
|
72
|
+
const error = useRouteError();
|
73
|
+
return /*#__PURE__*/_jsx(InternalErrorFallback, {
|
74
|
+
title: "Current route occurred an error",
|
75
|
+
desc: error.message
|
76
|
+
});
|
77
|
+
}
|
package/lib/Util/index.d.ts
CHANGED
@@ -86,4 +86,5 @@ export declare const getTranslation: (translations: TranslationsObject, locale:
|
|
86
86
|
fallbackLocale?: Locale;
|
87
87
|
defaultValue?: string;
|
88
88
|
}) => string;
|
89
|
+
export declare const lazyRetry: (fn: () => Promise<any>) => import("react").LazyExoticComponent<import("react").ComponentType<any>>;
|
89
90
|
export {};
|
package/lib/Util/index.js
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
/* eslint-disable no-bitwise */
|
2
|
+
import { lazy } from 'react';
|
2
3
|
import padStart from 'lodash/padStart';
|
3
4
|
import { getDIDMotifInfo, colors } from '@arcblock/did-motif';
|
4
5
|
import isNil from 'lodash/isNil';
|
6
|
+
import pRetry from 'p-retry';
|
5
7
|
import { DID_PREFIX, WELLKNOWN_SERVICE_PATH_PREFIX } from './constant';
|
6
8
|
let dateTool = null;
|
7
9
|
export function parseQuery(str) {
|
@@ -356,4 +358,22 @@ export const getTranslation = (translations, locale, options = {}) => {
|
|
356
358
|
translation = defaultValue;
|
357
359
|
}
|
358
360
|
return translation;
|
359
|
-
};
|
361
|
+
};
|
362
|
+
export const lazyRetry = fn => /*#__PURE__*/lazy(() => pRetry(async () => {
|
363
|
+
try {
|
364
|
+
return await fn();
|
365
|
+
} catch (error) {
|
366
|
+
// HACK: pRetry 不会对 TypeError 的错误进行重试,手动放行了部分 network error 的错误,但此处的错误是经过 react-router 包装过的,不适用于上述的判断,所以这里需要特殊逻辑来进行处理
|
367
|
+
if (error instanceof TypeError && !error.message.includes('Failed to fetch')) {
|
368
|
+
throw error;
|
369
|
+
}
|
370
|
+
if (error instanceof Error) {
|
371
|
+
throw new Error(error.message);
|
372
|
+
}
|
373
|
+
throw new Error('Unknown error');
|
374
|
+
}
|
375
|
+
},
|
376
|
+
// 只需要重试两次,加上原本的一次,总共三次
|
377
|
+
{
|
378
|
+
retries: 2
|
379
|
+
}));
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@arcblock/ux",
|
3
|
-
"version": "2.11.
|
3
|
+
"version": "2.11.10",
|
4
4
|
"description": "Common used react components for arcblock products",
|
5
5
|
"keywords": [
|
6
6
|
"react",
|
@@ -68,12 +68,12 @@
|
|
68
68
|
"react": ">=18.2.0",
|
69
69
|
"react-router-dom": ">=6.22.3"
|
70
70
|
},
|
71
|
-
"gitHead": "
|
71
|
+
"gitHead": "3c56d08b46485ae49fdfd32fc8c92df9c8ddf25e",
|
72
72
|
"dependencies": {
|
73
73
|
"@arcblock/did-motif": "^1.1.13",
|
74
|
-
"@arcblock/icons": "^2.11.
|
75
|
-
"@arcblock/nft-display": "^2.11.
|
76
|
-
"@arcblock/react-hooks": "^2.11.
|
74
|
+
"@arcblock/icons": "^2.11.10",
|
75
|
+
"@arcblock/nft-display": "^2.11.10",
|
76
|
+
"@arcblock/react-hooks": "^2.11.10",
|
77
77
|
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
|
78
78
|
"@fontsource/inter": "^5.0.16",
|
79
79
|
"@fontsource/ubuntu-mono": "^5.0.18",
|
@@ -103,6 +103,7 @@
|
|
103
103
|
"lodash": "^4.17.21",
|
104
104
|
"mui-datatables": "^4.3.0",
|
105
105
|
"notistack": "^2.0.5",
|
106
|
+
"p-retry": "^6.2.1",
|
106
107
|
"pako": "^2.1.0",
|
107
108
|
"qrcode.react": "^3.1.0",
|
108
109
|
"react-cookie-consent": "^6.4.1",
|
@@ -1,28 +1,51 @@
|
|
1
|
-
import {
|
1
|
+
import { Alert, AlertTitle, Box, Typography, type AlertProps } from '@mui/material';
|
2
|
+
import { ReactNode } from 'react';
|
3
|
+
import { useRouteError } from 'react-router-dom';
|
4
|
+
|
2
5
|
import Button from '../Button';
|
3
|
-
import { styled } from '../Theme';
|
4
6
|
|
5
|
-
|
7
|
+
interface InternalErrorFallbackProps {
|
6
8
|
title?: string;
|
7
9
|
desc: string;
|
8
|
-
|
10
|
+
extraContent?: ReactNode;
|
11
|
+
severity?: AlertProps['severity'];
|
9
12
|
}
|
10
13
|
|
11
14
|
function InternalErrorFallback({
|
12
15
|
title = 'Something went wrong...',
|
13
16
|
desc,
|
14
|
-
|
17
|
+
extraContent = null,
|
18
|
+
severity = 'error',
|
15
19
|
}: InternalErrorFallbackProps) {
|
20
|
+
const gotoHome = () => window.location.replace('/');
|
21
|
+
const refresh = () => window.location.reload();
|
22
|
+
|
16
23
|
return (
|
17
|
-
<
|
18
|
-
|
19
|
-
|
20
|
-
{
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
+
<Alert
|
25
|
+
severity={severity}
|
26
|
+
variant="outlined"
|
27
|
+
icon={false}
|
28
|
+
sx={{
|
29
|
+
justifyContent: 'center',
|
30
|
+
}}>
|
31
|
+
{title ? <AlertTitle>{title}</AlertTitle> : null}
|
32
|
+
{desc ? (
|
33
|
+
<Typography variant="body2" mb={1}>
|
34
|
+
{desc}
|
35
|
+
</Typography>
|
36
|
+
) : null}
|
37
|
+
{extraContent ?? (
|
38
|
+
<Box sx={{ display: 'flex', gap: 1, justifyContent: 'center', alignItems: 'center' }}>
|
39
|
+
<Button variant="outlined" color={severity} size="small" onClick={gotoHome}>
|
40
|
+
Home
|
41
|
+
</Button>
|
42
|
+
|
43
|
+
<Button variant="contained" color={severity} size="small" onClick={refresh}>
|
44
|
+
Refresh
|
45
|
+
</Button>
|
46
|
+
</Box>
|
24
47
|
)}
|
25
|
-
</
|
48
|
+
</Alert>
|
26
49
|
);
|
27
50
|
}
|
28
51
|
|
@@ -40,21 +63,19 @@ export interface ErrorFallbackRetryProps {
|
|
40
63
|
}
|
41
64
|
|
42
65
|
export function ErrorFallbackRetry({ error, resetErrorBoundary }: ErrorFallbackRetryProps) {
|
43
|
-
return
|
66
|
+
return (
|
67
|
+
<InternalErrorFallback
|
68
|
+
desc={error.message}
|
69
|
+
extraContent={
|
70
|
+
<Button variant="contained" color="error" size="small" onClick={resetErrorBoundary}>
|
71
|
+
Try again
|
72
|
+
</Button>
|
73
|
+
}
|
74
|
+
/>
|
75
|
+
);
|
44
76
|
}
|
45
77
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
color: ${(props) => props.theme.palette.error.main};
|
51
|
-
background-color: ${red[50]};
|
52
|
-
font-size: 14px;
|
53
|
-
h3 {
|
54
|
-
margin: 0;
|
55
|
-
font-size: 16px;
|
56
|
-
}
|
57
|
-
pre {
|
58
|
-
white-space: normal;
|
59
|
-
}
|
60
|
-
`;
|
78
|
+
export function ReactRouterErrorFallback() {
|
79
|
+
const error = useRouteError() as Error;
|
80
|
+
return <InternalErrorFallback title="Current route occurred an error" desc={error.message} />;
|
81
|
+
}
|
package/src/Util/index.ts
CHANGED
@@ -1,7 +1,9 @@
|
|
1
1
|
/* eslint-disable no-bitwise */
|
2
|
+
import { lazy } from 'react';
|
2
3
|
import padStart from 'lodash/padStart';
|
3
4
|
import { getDIDMotifInfo, colors } from '@arcblock/did-motif';
|
4
5
|
import isNil from 'lodash/isNil';
|
6
|
+
import pRetry from 'p-retry';
|
5
7
|
import { DID_PREFIX, WELLKNOWN_SERVICE_PATH_PREFIX } from './constant';
|
6
8
|
import type { $TSFixMe, Locale } from '../type';
|
7
9
|
|
@@ -456,3 +458,25 @@ export const getTranslation = (
|
|
456
458
|
|
457
459
|
return translation;
|
458
460
|
};
|
461
|
+
|
462
|
+
export const lazyRetry = (fn: () => Promise<any>) =>
|
463
|
+
lazy(() =>
|
464
|
+
pRetry(
|
465
|
+
async () => {
|
466
|
+
try {
|
467
|
+
return await fn();
|
468
|
+
} catch (error: unknown) {
|
469
|
+
// HACK: pRetry 不会对 TypeError 的错误进行重试,手动放行了部分 network error 的错误,但此处的错误是经过 react-router 包装过的,不适用于上述的判断,所以这里需要特殊逻辑来进行处理
|
470
|
+
if (error instanceof TypeError && !error.message.includes('Failed to fetch')) {
|
471
|
+
throw error;
|
472
|
+
}
|
473
|
+
if (error instanceof Error) {
|
474
|
+
throw new Error(error.message);
|
475
|
+
}
|
476
|
+
throw new Error('Unknown error');
|
477
|
+
}
|
478
|
+
},
|
479
|
+
// 只需要重试两次,加上原本的一次,总共三次
|
480
|
+
{ retries: 2 }
|
481
|
+
)
|
482
|
+
);
|