Browse Source

fix: address PR review feedback for offline features

- Use getIntl() with i18n key in requestErrorConfig instead of hardcoded
  English strings (matches CodeRabbit, Gemini, Copilot feedback)
- Add SSR guard for navigator.onLine in requestErrorConfig (Gemini)
- Replace <a> wrapping <Button> with <Button href> for valid HTML
- Extract getSubTitleId helper to eliminate nested ternary
- Move OfflineBanner to rootContainer layer to cover layout:false
  routes (login, register) that lack ProLayout

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
pull/11756/head
afc163 5 months ago
parent
commit
62b3368d7c
  1. 8
      src/app.tsx
  2. 19
      src/components/ErrorBoundary/index.tsx
  3. 14
      src/requestErrorConfig.ts

8
src/app.tsx

@ -149,7 +149,6 @@ export const layout: RunTimeLayoutConfig = ({
// if (initialState?.loading) return <PageLoading />;
return (
<>
<OfflineBanner />
{children}
<SettingDrawer
disableUrlParams
@ -187,5 +186,10 @@ export const request: RequestConfig = {
};
export function rootContainer(container: React.ReactNode) {
return <ErrorBoundary>{container}</ErrorBoundary>;
return (
<ErrorBoundary>
<OfflineBanner />
{container}
</ErrorBoundary>
);
}

19
src/components/ErrorBoundary/index.tsx

@ -10,6 +10,13 @@ function isChunkLoadError(error: Error): boolean {
);
}
function getSubTitleId(isChunkError: boolean, isOffline: boolean): string {
if (!isChunkError) return 'app.error.render.description';
return isOffline
? 'app.error.chunk.description.offline'
: 'app.error.chunk.description.online';
}
interface ErrorBoundaryState {
hasError: boolean;
error: Error | null;
@ -51,11 +58,7 @@ export default class ErrorBoundary extends React.Component<
id: isChunkError ? 'app.error.chunk.title' : 'app.error.render.title',
});
const subTitle = intl.formatMessage({
id: isChunkError
? isOffline
? 'app.error.chunk.description.offline'
: 'app.error.chunk.description.online'
: 'app.error.render.description',
id: getSubTitleId(isChunkError, isOffline),
});
return (
@ -68,9 +71,9 @@ export default class ErrorBoundary extends React.Component<
<Button type="primary" key="retry" onClick={this.handleRetry}>
{intl.formatMessage({ id: 'app.error.retry' })}
</Button>,
<a href="/" key="home">
<Button>{intl.formatMessage({ id: 'app.error.home' })}</Button>
</a>,
<Button href="/" key="home">
{intl.formatMessage({ id: 'app.error.home' })}
</Button>,
]}
/>
</Card>

14
src/requestErrorConfig.ts

@ -1,5 +1,6 @@
import type { RequestOptions } from '@@/plugin-request/request';
import type { RequestConfig } from '@umijs/max';
import { getIntl } from '@umijs/max';
import { message, notification } from 'antd';
// 错误处理方案: 错误类型
@ -77,18 +78,13 @@ export const errorConfig: RequestConfig = {
// 请求已经成功发起,但没有收到响应
// \`error.request\` 在浏览器中是 XMLHttpRequest 的实例,
// 而在node.js中是 http.ClientRequest 的实例
if (!navigator.onLine) {
message.error(
'Network unavailable. Please check your connection and try again.',
);
if (typeof navigator !== 'undefined' && !navigator.onLine) {
message.error(getIntl().formatMessage({ id: 'app.request.offline' }));
} else {
message.error('None response! Please retry.');
}
} else if (!navigator.onLine) {
// 发送请求时出了点问题(离线)
message.error(
'Network unavailable. Please check your connection and try again.',
);
} else if (typeof navigator !== 'undefined' && !navigator.onLine) {
message.error(getIntl().formatMessage({ id: 'app.request.offline' }));
} else {
// 发送请求时出了点问题
message.error('Request error, please retry.');

Loading…
Cancel
Save