svelte
svelte copied to clipboard
try block, like error boundary
Is your feature request related to a problem? Please describe.
I wonder would it possible to have a {#try}
logic block, such that anything goes inside, if error would be handled in the {:catch}
block, eg:
{#try}
<Component />
{:catch}
<div>Fallback uI </div>
{/try}
if an error thrown during init / update in <Component />
, then will see the Fallback UI instead.
Describe the solution you'd like A clear and concise description of what you want to happen.
Describe alternatives you've considered A clear and concise description of any alternative solutions or features you've considered.
How important is this feature to you? Note: the more honest and specific you are here the more we will take you seriously.
Additional context Add any other context or screenshots about the feature request here.
Good idea.
Maybe something like this would benefit even more, depending on the error getting thrown.
So basically like a switch
statement for catching errors.
<script>
import { GraphQLError } from 'graphql';
</script>
{#try}
<Component />
{:catch GraphQLError}
<div></div>
{:catch TypeError}
<div></div>
{:catch}
<div>Default fallback ui </div>
{/try}
Can see this being useful especially when including components from 3rd parties.
This has been brought up before, but I don't think there's a clear way that we could have this work. I don't think it would be too difficult to have handlers for exceptions that synchronously occur as part of an operation on the child component (instantiating it, or updating props for example), but there's not a good way to handle other exceptions that happen during the life of the component. The component would have to emit events (or do something else equivalent to that), but only when it appears inside a {#try}
. (In other cases, it should continue to throw exceptions as it currently does.) Every compiled component would have to support being run inside of a {#try}
, regardless of whether it ever actually is, because at compile time we can't tell that. This would be a burden on every component whether this feature was being used or not.
Yup, I just realised there's a RFC https://github.com/sveltejs/rfcs/pull/11 that brought up the exact same issue.
Every compiled component would have to support being run inside of a {#try}
That's how context works as well. Every component has to know which context it is currently mounted into.
I would like to propose a similar mechanism, where the error boundary of a component is assignes when mounted, just like context, (or it could be a special context key 🤔) So at the point of error, there's no bubbling up of errors, but rather catching it directly to the preassigned error boundaries
There was some discussion about this in the discord #future channel the other day, an I thought I'd jot down some notes here for posterity.
@halfnelson had created this error boundary proof-of-concept: https://svelte.dev/repl/006facb65ece4f808cd733e838783228?version=3.22.2
If we imagine some sort of event based API, then maybe extending the slot syntax would make more sense?
<script>
let error;
</script>
{#if error}
<p>Error: {error}</p>
{:else}
<slot on:error={({ detail }) => {
error = detail.message;
logMyErrorSomewhere(detail);
}} />
{/if}
I improved a bit on the REPL linked above, adding support for SSR and logging: https://svelte.dev/repl/9d44bbcf30444cd08cca6b85f07f2e2a?version=3.29.4
Has there been any progress on this? Or an alternate way to handle such errors?
I have JSON files containing data for my HTML pages, which contain keys like title
, summary
, blockquote
etc. This file is stored in a variable called post
and added into the page as follows:
<main>
<div class="container max-w-5xl mt-6 px-6">
<div class="pb-5 mb-5 border-b border-gray-100">
<h1 class="font-bold text-5xl">{post.title}</h1>
<h2>{post.summary}</h2>
</div>
<article class="prose lg:prose-xl my-4 mx-auto">
{#each post.text as text}
<p>{text.value}</p>
{/each}
</article>
<div class="flex flex-wrap">
{#each post.images as image}
<div class="w-full ">
<img src="{image.value.src}" alt="{image.value.alt}" class="w-full h-auto" />
</div>
{/each}
</div>
</div>
</main>
Now some posts might have a key while others may not. Currently, Svelte throws an error which stops my build process if any file is missing any key.
It would be good to 'try to look for this key, if it exists then add it otherwise just move on' kind of logic. I could implement an if-else block for each key but is there a more elegant way to handle this?
Solved my problem by using optional chaining.
{post?.title}
and so on.
@YamiOdymel, this feature request goes beyond simple error handling is more along the lines of React's Error Boundaries.
Hello, everyone. I am currently working on an RFC that can solve this issue.
Here's the RFC: sveltejs/rfcs#69
This seems like an RFC for tag extensions, which allows any kind of tags, but doesn't by itself add try/catch. I'd have to "import" that as custom syntax extension. If I understood correctly.
I personally would prefer exception/error handling to be a fundamental part of Svelte.
This concerns
a) errors when creating the sub-components
b) errors thrown from
b.1.) event handlers
b.2.) $:
reactivity statements,
b.3.) {}
expressions in the markup
b.4.) onMount()/onDestroy()
b.5.) and similar entry points, and
c) errors thrown up explicitly by JS code within the component.
Right now, a naive app implementation that follows the code patterns in the tutorial will not handle any errors. And handling all error properly requires either a lot of try/catch/emit boiler plate, or a custom error handling infrastructure.
Any updates due to Svelte5?
Wouldn't having a hook to deal with errors be better than handling errors in the markup? IMHO it'll make it easy to manipulate the errors.
<script>
import { onError } from "svelte";
import { logger } from "analytics";
let error;
onError((_error) => {
error = _error;
logger.error(_error);
})
</script>
{#if error}
<FallbackUI />
{:else}
<Component />
{/if}
Yes, indeed, I'd like that. This is great. Simple and meers all requirements.
Component level is the right granularity. (If I want to catch something more specific, I can use try/catch.)
This could catch all the other error classes, like exceptions in $:
statements, in markup {}
code, in the initial execution of the JS section code, and many other error classes.
Errors in sub-components should bubble up and be caught by the onError()
of the calling component. This would not force me to add an onError()
in every single component. Bubbling would also allow to show errors in a custom UI for a specific bigger component, including errors in generic sub-components. The error UI would depend on the enclosing component, which is what we need for complex user-friendly apps.