Show a recovery screen for app render errors (#1924)

* fix(app): show recovery screen for render failures

Render a retryable fallback with useful error details when the routed app tree throws during render instead of leaving the app blank.

* test(app): cover root error details without mounting

Move caught-value formatting into a pure module, cover AggregateError fields without duplicate output, and remove the component-mounted test.

* fix(app): keep empty error details caught

* fix(app): preserve nullable aggregate errors

* fix(app): guard malformed error details

* fix(app): handle recursive error causes

* fix(app): guard error detail formatting failures

* fix(app): localize root error fallback

* fix(app): keep root error fallback on existing i18n
This commit is contained in:
Mohamed Boudra
2026-07-09 00:06:29 +08:00
committed by GitHub
parent 6ca1f4dac5
commit cab0e4b3f8
12 changed files with 494 additions and 16 deletions
+6
View File
@@ -1048,6 +1048,12 @@ export const ar: TranslationResources = {
},
},
},
rootError: {
kicker: "حدث خطأ",
title: "واجه Paseo مشكلة.",
body: "جرّب مرة أخرى لإعادة تحميل التطبيق. إذا استمر حدوث ذلك، فأرفق التفاصيل أدناه عند الإبلاغ عنه.",
details: "التفاصيل",
},
startup: {
errorTitle: "حدث خطأ ما",
errorDescription:
+6
View File
@@ -1055,6 +1055,12 @@ export const en = {
},
},
},
rootError: {
kicker: "Something went wrong",
title: "Paseo ran into a problem.",
body: "Try again to reload the app. If this keeps happening, include the details below when you report it.",
details: "Details",
},
startup: {
errorTitle: "Something went wrong",
errorDescription:
+6
View File
@@ -1084,6 +1084,12 @@ export const es: TranslationResources = {
},
},
},
rootError: {
kicker: "Algo salió mal",
title: "Paseo tuvo un problema.",
body: "Vuelve a intentarlo para recargar la app. Si sigue ocurriendo, incluye los detalles de abajo al reportarlo.",
details: "Detalles",
},
startup: {
errorTitle: "algo salió mal",
errorDescription:
+6
View File
@@ -1086,6 +1086,12 @@ export const fr: TranslationResources = {
},
},
},
rootError: {
kicker: "Une erreur s'est produite",
title: "Paseo a rencontré un problème.",
body: "Réessayez pour recharger l'application. Si cela continue, joignez les détails ci-dessous au signalement.",
details: "Détails",
},
startup: {
errorTitle: "Quelque chose s'est mal passé",
errorDescription:
+6
View File
@@ -1062,6 +1062,12 @@ export const ja: TranslationResources = {
},
},
},
rootError: {
kicker: "問題が発生しました",
title: "Paseo で問題が発生しました。",
body: "アプリを再読み込みするにはもう一度お試しください。繰り返し発生する場合は、以下の詳細を添えて報告してください。",
details: "詳細",
},
startup: {
errorTitle: "問題が発生しました",
errorDescription:
+6
View File
@@ -1070,6 +1070,12 @@ export const ptBR: TranslationResources = {
},
},
},
rootError: {
kicker: "Algo deu errado",
title: "O Paseo encontrou um problema.",
body: "Tente novamente para recarregar o app. Se isso continuar acontecendo, inclua os detalhes abaixo ao relatar o problema.",
details: "Detalhes",
},
startup: {
errorTitle: "Algo deu errado",
errorDescription:
+6
View File
@@ -1074,6 +1074,12 @@ export const ru: TranslationResources = {
},
},
},
rootError: {
kicker: "Что-то пошло не так",
title: "В Paseo возникла проблема.",
body: "Попробуйте снова перезагрузить приложение. Если это повторяется, приложите приведенные ниже подробности к отчету.",
details: "Подробности",
},
startup: {
errorTitle: "Что- то пошло не так",
errorDescription:
+6
View File
@@ -1034,6 +1034,12 @@ export const zhCN: TranslationResources = {
},
},
},
rootError: {
kicker: "出现问题",
title: "Paseo 遇到了问题。",
body: "请重试以重新加载应用。如果问题持续发生,请在报告时附上下面的详细信息。",
details: "详情",
},
startup: {
errorTitle: "出现问题",
errorDescription: "本地服务器启动失败。如果持续发生,请在 GitHub 报告问题并附上下方日志。",