Browse Source

feat: add soft retry for chunk errors and update all locales

Split the single retry button into two actions:
- "Retry" (soft): clears failed chunk scripts and resets ErrorBoundary
  state for chunk load errors only
- "Reload Page" (hard): full page refresh, available for all errors

Update all 8 locale files with new app.error.reload key and change
app.error.retry from "refresh/reload" to "retry" semantics.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
pull/11756/head
afc163 5 months ago
parent
commit
ddbb1ea75c
  1. 60
      src/components/ErrorBoundary/index.tsx
  2. 3
      src/locales/bn-BD/pwa.ts
  3. 9
      src/locales/en-US/pwa.ts
  4. 3
      src/locales/fa-IR/pwa.ts
  5. 3
      src/locales/id-ID/pwa.ts
  6. 3
      src/locales/ja-JP/pwa.ts
  7. 3
      src/locales/pt-BR/pwa.ts
  8. 7
      src/locales/zh-CN/pwa.ts
  9. 3
      src/locales/zh-TW/pwa.ts

60
src/components/ErrorBoundary/index.tsx

@ -17,15 +17,40 @@ function getSubTitleId(isChunkError: boolean, isOffline: boolean): string {
: 'app.error.chunk.description.online'; : 'app.error.chunk.description.online';
} }
/**
* Remove failed chunk script/link tags so the bundler runtime can retry loading.
* Utoopack caches failed chunks as rejected promises; removing the DOM elements
* and clearing its internal cache isn't possible via public API, but removing
* the script tags gives us a clean slate on the next retry.
*/
function removeFailedChunkScripts() {
const scripts = document.querySelectorAll(
'script[src][data-failed], link[href][data-failed]',
);
for (const el of scripts) el.remove();
}
function renderErrorFallback( function renderErrorFallback(
error: Error, error: Error,
isOnline: boolean, isOnline: boolean,
onReload: () => void,
onRetry: () => void, onRetry: () => void,
) { ) {
const intl = getIntl(); const intl = getIntl();
const isOffline = !isOnline; const isOffline = !isOnline;
const isChunkError = isChunkLoadError(error); const isChunkError = isChunkLoadError(error);
const subTitleId = getSubTitleId(isChunkError, isOffline);
const retryButton = isChunkError ? (
<Button type="primary" key="retry" onClick={onRetry}>
{intl.formatMessage({
id: 'app.error.retry',
defaultMessage: 'Retry',
})}
</Button>
) : null;
return ( return (
<div style={{ padding: 24 }}> <div style={{ padding: 24 }}>
<Card variant="borderless"> <Card variant="borderless">
@ -40,19 +65,24 @@ function renderErrorFallback(
: 'Something went wrong', : 'Something went wrong',
})} })}
subTitle={intl.formatMessage({ subTitle={intl.formatMessage({
id: getSubTitleId(isChunkError, isOffline), id: subTitleId,
defaultMessage: defaultMessage:
isChunkError && isOffline isChunkError && isOffline
? 'Your network connection has been lost. Please check your connection and refresh.' ? 'Your network connection has been lost. Please check your connection and reload.'
: isChunkError : isChunkError
? 'Page resources failed to load. Please refresh and try again.' ? 'Page resources failed to load. Please reload and try again.'
: 'Sorry, an error occurred on this page. Please refresh or go back to the home page.', : 'Sorry, an error occurred on this page. Please reload or go back to the home page.',
})} })}
extra={[ extra={[
<Button type="primary" key="retry" onClick={onRetry}> retryButton,
<Button
type={isChunkError ? 'default' : 'primary'}
key="reload"
onClick={onReload}
>
{intl.formatMessage({ {intl.formatMessage({
id: 'app.error.retry', id: 'app.error.reload',
defaultMessage: 'Refresh', defaultMessage: 'Reload Page',
})} })}
</Button>, </Button>,
<Button href="/" key="home"> <Button href="/" key="home">
@ -61,7 +91,7 @@ function renderErrorFallback(
defaultMessage: 'Back Home', defaultMessage: 'Back Home',
})} })}
</Button>, </Button>,
]} ].filter(Boolean)}
/> />
</Card> </Card>
</div> </div>
@ -111,12 +141,15 @@ export default class ErrorBoundary extends React.Component<
console.error('[ErrorBoundary]', error, info.componentStack); console.error('[ErrorBoundary]', error, info.componentStack);
} }
/** Soft retry: clear failed scripts, reset state, let React re-render. */
handleRetry = () => { handleRetry = () => {
if (this.state.error && isChunkLoadError(this.state.error)) { removeFailedChunkScripts();
window.location.reload(); this.setState({ hasError: false, error: null });
} else { };
this.setState({ hasError: false, error: null });
} /** Hard reload: full page refresh. */
handleReload = () => {
window.location.reload();
}; };
render() { render() {
@ -124,6 +157,7 @@ export default class ErrorBoundary extends React.Component<
return renderErrorFallback( return renderErrorFallback(
this.state.error, this.state.error,
this.isOnline, this.isOnline,
this.handleReload,
this.handleRetry, this.handleRetry,
); );
} }

3
src/locales/bn-BD/pwa.ts

@ -8,7 +8,8 @@ export default {
'app.error.render.title': 'কিছু ভুল হয়েছে', 'app.error.render.title': 'কিছু ভুল হয়েছে',
'app.error.render.description': 'app.error.render.description':
'দুঃখিত, এই পৃষ্ঠায় একটি ত্রুটি ঘটেছে। দয়া করে রিফ্রেশ করুন বা হোম পৃষ্ঠায় ফিরে যান।', 'দুঃখিত, এই পৃষ্ঠায় একটি ত্রুটি ঘটেছে। দয়া করে রিফ্রেশ করুন বা হোম পৃষ্ঠায় ফিরে যান।',
'app.error.retry': 'রিফ্রেশ', 'app.error.retry': 'আবার চেষ্টা করুন',
'app.error.reload': 'পৃষ্ঠা রিফ্রেশ করুন',
'app.error.home': 'হোমে ফিরে যান', 'app.error.home': 'হোমে ফিরে যান',
'app.request.offline': 'app.request.offline':
'নেটওয়ার্ক অনুপলব্ধ। আপনার সংযোগ পরীক্ষা করুন এবং আবার চেষ্টা করুন।', 'নেটওয়ার্ক অনুপলব্ধ। আপনার সংযোগ পরীক্ষা করুন এবং আবার চেষ্টা করুন।',

9
src/locales/en-US/pwa.ts

@ -3,13 +3,14 @@ export default {
'You are currently offline. Some features may be unavailable.', 'You are currently offline. Some features may be unavailable.',
'app.error.chunk.title': 'Failed to load page', 'app.error.chunk.title': 'Failed to load page',
'app.error.chunk.description.offline': 'app.error.chunk.description.offline':
'Your network connection has been lost. Please check your connection and refresh.', 'Your network connection has been lost. Please check your connection and reload.',
'app.error.chunk.description.online': 'app.error.chunk.description.online':
'Page resources failed to load. Please refresh and try again.', 'Page resources failed to load. Please reload and try again.',
'app.error.render.title': 'Something went wrong', 'app.error.render.title': 'Something went wrong',
'app.error.render.description': 'app.error.render.description':
'Sorry, an error occurred on this page. Please refresh or go back to the home page.', 'Sorry, an error occurred on this page. Please reload or go back to the home page.',
'app.error.retry': 'Refresh', 'app.error.retry': 'Retry',
'app.error.reload': 'Reload Page',
'app.error.home': 'Back Home', 'app.error.home': 'Back Home',
'app.request.offline': 'app.request.offline':
'Network unavailable. Please check your connection and try again.', 'Network unavailable. Please check your connection and try again.',

3
src/locales/fa-IR/pwa.ts

@ -9,7 +9,8 @@ export default {
'app.error.render.title': 'خطایی رخ داد', 'app.error.render.title': 'خطایی رخ داد',
'app.error.render.description': 'app.error.render.description':
'متأسفانه، در این صفحه خطایی رخ داد. لطفاً صفحه را بارگذاری مجدد کنید یا به صفحه اصلی بازگردید.', 'متأسفانه، در این صفحه خطایی رخ داد. لطفاً صفحه را بارگذاری مجدد کنید یا به صفحه اصلی بازگردید.',
'app.error.retry': 'بارگذاری مجدد', 'app.error.retry': 'تلاش مجدد',
'app.error.reload': 'بارگذاری مجدد صفحه',
'app.error.home': 'بازگشت به صفحه اصلی', 'app.error.home': 'بازگشت به صفحه اصلی',
'app.request.offline': 'app.request.offline':
'شبکه در دسترس نیست. لطفاً اتصال خود را بررسی و دوباره تلاش کنید.', 'شبکه در دسترس نیست. لطفاً اتصال خود را بررسی و دوباره تلاش کنید.',

3
src/locales/id-ID/pwa.ts

@ -9,7 +9,8 @@ export default {
'app.error.render.title': 'Terjadi kesalahan', 'app.error.render.title': 'Terjadi kesalahan',
'app.error.render.description': 'app.error.render.description':
'Maaf, terjadi kesalahan pada halaman ini. Muat ulang halaman atau kembali ke beranda.', 'Maaf, terjadi kesalahan pada halaman ini. Muat ulang halaman atau kembali ke beranda.',
'app.error.retry': 'Muat Ulang', 'app.error.retry': 'Coba Lagi',
'app.error.reload': 'Muat Ulang Halaman',
'app.error.home': 'Kembali ke Beranda', 'app.error.home': 'Kembali ke Beranda',
'app.request.offline': 'app.request.offline':
'Jaringan tidak tersedia. Periksa koneksi Anda dan coba lagi.', 'Jaringan tidak tersedia. Periksa koneksi Anda dan coba lagi.',

3
src/locales/ja-JP/pwa.ts

@ -9,7 +9,8 @@ export default {
'app.error.render.title': 'エラーが発生しました', 'app.error.render.title': 'エラーが発生しました',
'app.error.render.description': 'app.error.render.description':
'申し訳ありません、ページでエラーが発生しました。ページを再読み込みするか、ホームに戻ってください。', '申し訳ありません、ページでエラーが発生しました。ページを再読み込みするか、ホームに戻ってください。',
'app.error.retry': '再読み込み', 'app.error.retry': '再試行',
'app.error.reload': 'ページを再読み込み',
'app.error.home': 'ホームに戻る', 'app.error.home': 'ホームに戻る',
'app.request.offline': 'app.request.offline':
'ネットワークに接続できません。接続を確認して再試行してください。', 'ネットワークに接続できません。接続を確認して再試行してください。',

3
src/locales/pt-BR/pwa.ts

@ -9,7 +9,8 @@ export default {
'app.error.render.title': 'Algo deu errado', 'app.error.render.title': 'Algo deu errado',
'app.error.render.description': 'app.error.render.description':
'Desculpe, ocorreu um erro nesta página. Atualize a página ou volte para a página inicial.', 'Desculpe, ocorreu um erro nesta página. Atualize a página ou volte para a página inicial.',
'app.error.retry': 'Atualizar', 'app.error.retry': 'Tentar novamente',
'app.error.reload': 'Atualizar página',
'app.error.home': 'Voltar ao Início', 'app.error.home': 'Voltar ao Início',
'app.request.offline': 'app.request.offline':
'Rede indisponível. Verifique sua conexão e tente novamente.', 'Rede indisponível. Verifique sua conexão e tente novamente.',

7
src/locales/zh-CN/pwa.ts

@ -2,12 +2,13 @@ export default {
'app.network.offline': '当前处于离线状态,部分功能可能不可用', 'app.network.offline': '当前处于离线状态,部分功能可能不可用',
'app.error.chunk.title': '页面加载失败', 'app.error.chunk.title': '页面加载失败',
'app.error.chunk.description.offline': 'app.error.chunk.description.offline':
'网络连接已断开,请检查网络后刷新页面。', '网络连接已断开,请检查网络后重新加载。',
'app.error.chunk.description.online': '页面资源加载失败,请刷新页面重试。', 'app.error.chunk.description.online': '页面资源加载失败,请重新加载重试。',
'app.error.render.title': '页面出现错误', 'app.error.render.title': '页面出现错误',
'app.error.render.description': 'app.error.render.description':
'抱歉,页面遇到了一些问题,请刷新页面或返回首页。', '抱歉,页面遇到了一些问题,请刷新页面或返回首页。',
'app.error.retry': '刷新页面', 'app.error.retry': '重新加载',
'app.error.reload': '刷新页面',
'app.error.home': '返回首页', 'app.error.home': '返回首页',
'app.request.offline': '网络不可用,请检查网络连接后重试。', 'app.request.offline': '网络不可用,请检查网络连接后重试。',
}; };

3
src/locales/zh-TW/pwa.ts

@ -8,7 +8,8 @@ export default {
'app.error.render.title': '頁面出現錯誤', 'app.error.render.title': '頁面出現錯誤',
'app.error.render.description': 'app.error.render.description':
'抱歉,頁面遇到了一些問題,請重新整理頁面或返回首頁。', '抱歉,頁面遇到了一些問題,請重新整理頁面或返回首頁。',
'app.error.retry': '重新整理', 'app.error.retry': '重試',
'app.error.reload': '重新整理頁面',
'app.error.home': '返回首頁', 'app.error.home': '返回首頁',
'app.request.offline': '網路不可用,請檢查網路連線後重試。', 'app.request.offline': '網路不可用,請檢查網路連線後重試。',
}; };

Loading…
Cancel
Save