Skip to content

Commit

Permalink
Error boundary to prevent TileView errors from causing crash.
Browse files Browse the repository at this point in the history
  • Loading branch information
amyjko committed Dec 9, 2024
1 parent d11e52b commit a8c7497
Show file tree
Hide file tree
Showing 14 changed files with 217 additions and 131 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ Dates are in `YYYY-MM-DD` format and versions are in [semantic versioning](http:

## 0.13.2 2024-12-09

### Added

- Error boundary to prevent `TileView` errors from causing crash.

### Maintenance

- Updated all minor releases of dependencies except for Firebase.
Expand Down
136 changes: 82 additions & 54 deletions src/components/project/TileView.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import TileSymbols from './TileSymbols';
import FullscreenIcon from './FullscreenIcon.svelte';
import type Bounds from './Bounds';
import Note from '@components/widgets/Note.svelte';
interface Props {
project: Project;
Expand Down Expand Up @@ -267,65 +268,85 @@
}px`}
bind:this={view}
>
<!-- Render the toolbar -->
<div class="header" style:color={foreground} style:fill={foreground}>
{#if !layout.isFullscreen()}
<Button
<svelte:boundary>
{#snippet failed(error, reset)}
<div class="error">
<h2>{$locales.get((l) => l.ui.project.error.tile)}</h2>
<p
><Button tip="Reset" action={reset} background
>{$locales.get(
(l) => l.ui.project.error.reset,
)}</Button
></p
>
<Note>{'' + error}</Note>
</div>
{/snippet}

<!-- Render the toolbar -->
<div
class="header"
style:color={foreground}
style:fill={foreground}
>
{#if !layout.isFullscreen()}
<Button
background={background !== null}
padding={false}
tip={$locales.get((l) => l.ui.tile.button.collapse)}
action={() => mode(Mode.Collapsed)}>–</Button
>
{/if}
<Toggle
tips={$locales.get((l) => l.ui.tile.toggle.fullscreen)}
on={fullscreen}
background={background !== null}
padding={false}
tip={$locales.get((l) => l.ui.tile.button.collapse)}
action={() => mode(Mode.Collapsed)}>–</Button
toggle={() => setFullscreen(!fullscreen)}
>
{/if}
<Toggle
tips={$locales.get((l) => l.ui.tile.toggle.fullscreen)}
on={fullscreen}
background={background !== null}
toggle={() => setFullscreen(!fullscreen)}
>
<FullscreenIcon />
</Toggle>
<div class="name" class:source={tile.isSource()}>
{#if editable && tile.isSource()}
<Emoji>{Glyphs.Program.symbols}</Emoji>
<TextField
text={tile
.getSource(project)
?.getPreferredName($locales.getLocales())}
description={$locales.get(
(l) => l.ui.source.field.name.description,
)}
placeholder={$locales.get(
(l) => l.ui.source.field.name.placeholder,
<FullscreenIcon />
</Toggle>
<div class="name" class:source={tile.isSource()}>
{#if editable && tile.isSource()}
<Emoji>{Glyphs.Program.symbols}</Emoji>
<TextField
text={tile
.getSource(project)
?.getPreferredName($locales.getLocales())}
description={$locales.get(
(l) => l.ui.source.field.name.description,
)}
placeholder={$locales.get(
(l) => l.ui.source.field.name.placeholder,
)}
validator={(text) => isName(text)}
changed={handleRename}
/>
{:else}
<Emoji>{TileSymbols[tile.kind]}</Emoji>{tile.getName(
project,
$locales,
)}
validator={(text) => isName(text)}
changed={handleRename}
/>
{:else}
<Emoji>{TileSymbols[tile.kind]}</Emoji>{tile.getName(
project,
$locales,
)}
{/if}
{@render title()}
{/if}
{@render title()}
</div>
<div class="toolbar">
{@render extra?.()}
</div>
</div>
<div class="toolbar">
{@render extra?.()}
<!-- Render the content -->
<div class="main" class:rtl={$locales.getDirection() === 'rtl'}>
<div class="content" onscroll={() => scroll()}>
{@render content()}
</div>
<div class="margin">{@render margin?.()}</div>
</div>
</div>
<!-- Render the content -->
<div class="main" class:rtl={$locales.getDirection() === 'rtl'}>
<div class="content" onscroll={() => scroll()}>
{@render content()}
</div>
<div class="margin">{@render margin?.()}</div>
</div>
<!-- Render a focus indicator. We do this instead of an outline to avoid content form overlapping an inset CSS outline. -->
{#if focuscontent}
<div class="focus-indicator"></div>
{/if}
<!-- Render the footer -->
<div class="footer">{@render footer?.()}</div>
<!-- Render a focus indicator. We do this instead of an outline to avoid content form overlapping an inset CSS outline. -->
{#if focuscontent}
<div class="focus-indicator"></div>
{/if}
<!-- Render the footer -->
<div class="footer">{@render footer?.()}</div>
</svelte:boundary>
</section>
</div>

Expand Down Expand Up @@ -513,4 +534,11 @@
.name.source {
color: var(--wordplay-foreground);
}
.error {
padding: var(--wordplay-spacing);
background: var(--wordplay-error);
color: var(--wordplay-background);
height: 100%;
}
</style>
4 changes: 4 additions & 0 deletions src/locale/UITexts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ type UITexts = {
unknown: string;
/** The error to show if translation wasn't possible */
translate: string;
/** The message for an error in a tile */
tile: string;
/** The button label for an error reset */
reset: string;
};
button: {
/** Shows the sharing dialog */
Expand Down
4 changes: 3 additions & 1 deletion src/locale/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -4074,7 +4074,9 @@
"project": {
"error": {
"unknown": "This project doesn't exist or isn't public.",
"translate": "There was a problem translating your project."
"translate": "There was a problem translating your project.",
"tile": "Oops, there was an error",
"reset": "Attempt to reset..."
},
"button": {
"showCollaborators": "show collaborators dialog",
Expand Down
37 changes: 30 additions & 7 deletions static/locales/de-DE/de-DE.json
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
"Select": "wählen",
"Insert": "einfügen",
"Update": "updaten",
"Delete": "löschen",
"Delete": "löschen",
"Union": "Union",
"Stream": "Datenstrom",
"Change": "verändern",
Expand Down Expand Up @@ -453,7 +453,8 @@
"ExpectedEndingExpression": "$~Ich brauche einen Ausdruck.",
"IgnoredExpression": {
"primary": "$~Ich werde das oben Gesagte ignorieren.",
"secondary": "$~@Block, ignorier mich nicht!"
"secondary": "$~@Block, ignorier mich nicht!",
"resolution": "$~Meinten Sie, dass dies ein @BinaryEvaluate statt eines @UnaryEvaluate sein sollte? Ich kann ein Leerzeichen hinzufügen, damit ich weiß, dass Sie das gemeint haben."
}
}
},
Expand Down Expand Up @@ -3315,7 +3316,8 @@
"gravity": {
"doc": "$~Die Schwerkraft, die auf die Ausgabe angewendet werden soll, deren Platz in @Motion ist.",
"names": "$~Schwere"
}
},
"defaultDescription": "$~Stufe $2[$2 |]von $1 gibt $3 aus[mit Rahmen $3|] $4"
},
"Group": {
"names": ["$~🔳", "$~Gruppe"],
Expand Down Expand Up @@ -3415,7 +3417,8 @@
"style": {
"doc": "$~Dasselbe wie @Phrase/Stil!",
"names": "$~Stil"
}
},
"defaultDescription": "$~$1[$1|] $2 $3"
},
"Phrase": {
"names": ["💬", "Satzglied"],
Expand Down Expand Up @@ -3526,7 +3529,8 @@
"style": {
"doc": "$~Der zu verwendende Animationsstil beim Wechsel an eine andere Stelle auf der Bühne.",
"names": "$~Stil"
}
},
"defaultDescription": "$~$3[$3 Takt |]Phrase $1 $2[benannt $2|] $4[$4|] $5"
},
"Arrangement": {
"names": ["Arrangement"],
Expand Down Expand Up @@ -3661,6 +3665,12 @@
"style": {
"doc": "$~Der Animationsstil, den ich verwenden sollte.",
"names": "$~Stil"
},
"description": {
"doc": [
"$~Eine Beschreibung für Zuschauer, die keine visuelle Ausgabe sehen können."
],
"names": "$~Beschreibung"
}
},
"Form": {
Expand Down Expand Up @@ -4042,7 +4052,9 @@
"project": {
"error": {
"unknown": "$~Dieses Projekt existiert nicht oder ist nicht öffentlich.",
"translate": "$~Beim Übersetzen Ihres Projekts ist ein Problem aufgetreten."
"translate": "$~Beim Übersetzen Ihres Projekts ist ein Problem aufgetreten.",
"tile": "$~Hoppla, da ist ein Fehler aufgetreten.",
"reset": "$~Versuch zum Zurücksetzen..."
},
"button": {
"showCollaborators": "$~Dialog für Mitarbeiter anzeigen",
Expand Down Expand Up @@ -4224,7 +4236,8 @@
"redo": "$~Rückgängig gemachte Bearbeitung wiederholen",
"search": "$~Suche nach einzufügenden Sonderzeichen",
"tidy": "$~ordentlicher Abstand",
"elide": "$~Elision umschalten"
"elide": "$~Elision umschalten",
"insertDocs": "$~Erklärungssymbol einfügen"
}
},
"annotations": {
Expand Down Expand Up @@ -4262,6 +4275,9 @@
},
"button": {
"submit": "$~diese Chat-Nachricht senden"
},
"options": {
"locale": "$~Wählen Sie die Sprache für die Ausgabe"
}
},
"timeline": {
Expand Down Expand Up @@ -4407,6 +4423,13 @@
"$~Code lokalisieren, wenn verfügbar",
"$~Code lokalisieren, aber Symbole bevorzugen"
]
},
"lines": {
"label": "$~Zeilennummern",
"modes": [
"$~Zeilennummern im Textmodus anzeigen",
"$~Zeilennummern im Textmodus nicht anzeigen"
]
}
},
"options": {
Expand Down
9 changes: 5 additions & 4 deletions static/locales/es-MX/es-MX.json
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,7 @@
"Puedo combinar con \\/\\ para formar unidades de proporción, como \\17manzanas/día\\ y con \\^\\ para formar unidades exponenciales como \\9.8m/s^2\\.",
"Siempre debo ir después de @Number. Si no lo hago, podrían confudirme con @Reference, ¡lo cual sería bastantate embarazoso!",
"Siempre debo ir después de @Number. Si no lo hago, podrían confudirme con @Reference, ¡lo cual sería bastantate embarazoso!",
"También soy bastante bueno para encontrar inconsistencies entre unidades. Por ejemplo, !\\1gato + 1perro\\ no tiene ningún sentido!",
"Si alguna vez deseas convertir entre diferentes valores de unidades, hable con @Convert."
"También soy bastante bueno para encontrar inconsistencies entre unidades. Por ejemplo, !\\1gato + 1perro\\ no tiene ningún sentido!"
]
},
"Doc": {
Expand Down Expand Up @@ -4040,7 +4039,9 @@
"project": {
"error": {
"unknown": "Esta actuación no existe o no es pública.",
"translate": "$~Hubo un problema al traducir tu proyecto."
"translate": "$~Hubo un problema al traducir tu proyecto.",
"tile": "$~Ups, hubo un error.",
"reset": "$~Intentar reiniciar..."
},
"button": {
"showCollaborators": "mostrar a los colaboradores el diálogo",
Expand Down Expand Up @@ -4531,7 +4532,7 @@
],
"beta": [
"Wordplay está en *beta*. Esto significa que la funcionalidad puede cambiar o no funcionar como se espera.",
"¡Pero también significa que queremos tus comentarios! Informa sobre errores y comparte ideas en <Discord@https://discord.gg/Jh2Qq9husy>, o <GitHub@https://github.com/wordplaydev/wordplay/issues>. Consulta nuestros <planes 1.0@https://github.com/wordplaydev/wordplay/milestones/1.0> y <contribuir@https://github.com/wordplaydev/wordplay/wiki/contribute> si puedes hacerlo."
null
],
"link": {
"about": "¿Por qué existe este lugar?",
Expand Down
4 changes: 3 additions & 1 deletion static/locales/example/example.json
Original file line number Diff line number Diff line change
Expand Up @@ -3077,7 +3077,9 @@
"project": {
"error": {
"unknown": "$?",
"translate": "$?"
"translate": "$?",
"tile": "$?",
"reset": "$?"
},
"button": {
"showCollaborators": "$?",
Expand Down
4 changes: 3 additions & 1 deletion static/locales/fr-FR/fr-FR.json
Original file line number Diff line number Diff line change
Expand Up @@ -4073,7 +4073,9 @@
"project": {
"error": {
"unknown": "$~Ce projet n'existe pas ou n'est pas public.",
"translate": "$~Il y a eu un problème lors de la traduction de votre projet."
"translate": "$~Il y a eu un problème lors de la traduction de votre projet.",
"tile": "$~Oups, il y a eu une erreur.",
"reset": "$~Tenter de réinitialiser..."
},
"button": {
"showCollaborators": "$~Afficher la boîte de dialogue des collaborateurs",
Expand Down
4 changes: 3 additions & 1 deletion static/locales/hi-IN/hi-IN.json
Original file line number Diff line number Diff line change
Expand Up @@ -4073,7 +4073,9 @@
"project": {
"error": {
"unknown": "$~यह परियोजना मौजूद नहीं है या सार्वजनिक नहीं है।",
"translate": "$~आपके प्रोजेक्ट का अनुवाद करने में समस्या हुई."
"translate": "$~आपके प्रोजेक्ट का अनुवाद करने में समस्या हुई.",
"tile": "$~ओह, एक त्रुटि हुई.",
"reset": "$~रीसेट करने का प्रयास..."
},
"button": {
"showCollaborators": "$~सहयोगी संवाद दिखाएं",
Expand Down
4 changes: 3 additions & 1 deletion static/locales/ja-JP/ja-JP.json
Original file line number Diff line number Diff line change
Expand Up @@ -4073,7 +4073,9 @@
"project": {
"error": {
"unknown": "$~このプロジェクトは存在しないか、公開されていません。",
"translate": "$~プロジェクトの翻訳中に問題が発生しました。"
"translate": "$~プロジェクトの翻訳中に問題が発生しました。",
"tile": "$~申し訳ございません。エラーが発生しました。",
"reset": "$~リセットを試行します..."
},
"button": {
"showCollaborators": "$~共同作業者ダイアログを表示",
Expand Down
4 changes: 3 additions & 1 deletion static/locales/ko-KR/ko-KR.json
Original file line number Diff line number Diff line change
Expand Up @@ -4073,7 +4073,9 @@
"project": {
"error": {
"unknown": "$~이 프로젝트는 존재하지 않거나 공개되지 않습니다.",
"translate": "$~프로젝트를 번역하는 중에 문제가 발생했습니다."
"translate": "$~프로젝트를 번역하는 중에 문제가 발생했습니다.",
"tile": "$~아, 오류가 발생했습니다.",
"reset": "$~재설정을 시도하세요..."
},
"button": {
"showCollaborators": "$~공동작업자 대화상자 표시",
Expand Down
4 changes: 3 additions & 1 deletion static/locales/zh-CN/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -4025,7 +4025,9 @@
"project": {
"error": {
"unknown": "该演出不存在或未公开",
"translate": "翻译你的项目时出现问题。"
"translate": "翻译你的项目时出现问题。",
"tile": "$~糟糕,出现错误。",
"reset": "$~尝试重置..."
},
"button": {
"showCollaborators": "显示合作者对话框",
Expand Down
Loading

0 comments on commit a8c7497

Please sign in to comment.