Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

try block, like error boundary #3733

Open
tanhauhau opened this issue Oct 18, 2019 · 15 comments
Open

try block, like error boundary #3733

tanhauhau opened this issue Oct 18, 2019 · 15 comments
Labels
awaiting submitter needs a reproduction, or clarification feature request popular more than 20 upthumbs temp-stale
Milestone

Comments

@tanhauhau
Copy link
Member

tanhauhau commented Oct 18, 2019

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.

@marcus-sa
Copy link

marcus-sa commented Oct 18, 2019

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}

@MintyMods
Copy link

Can see this being useful especially when including components from 3rd parties.

@Conduitry
Copy link
Member

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.

@Conduitry Conduitry added the awaiting submitter needs a reproduction, or clarification label Oct 18, 2019
@tanhauhau
Copy link
Member Author

Yup, I just realised there's a RFC sveltejs/rfcs#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

@jonatansberg
Copy link

jonatansberg commented May 11, 2020

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}

@jonatansberg
Copy link

I improved a bit on the REPL linked above, adding support for SSR and logging:
https://svelte.dev/repl/9d44bbcf30444cd08cca6b85f07f2e2a?version=3.29.4

@thedivtagguy
Copy link

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?

@thedivtagguy
Copy link

Solved my problem by using optional chaining.
{post?.title} and so on.

@mrcasual
Copy link

@YamiOdymel, this feature request goes beyond simple error handling is more along the lines of React's Error Boundaries.

@ghost
Copy link

ghost commented Nov 12, 2022

Hello, everyone. I am currently working on an RFC that can solve this issue.

@ghost
Copy link

ghost commented Nov 13, 2022

Here's the RFC: sveltejs/rfcs#69

@benbucksch
Copy link
Contributor

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.

@emil14
Copy link

emil14 commented Feb 23, 2024

Any updates due to Svelte5?

@Rich-Harris Rich-Harris added this to the 5.x milestone Apr 2, 2024
@sifat-at-work
Copy link

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}

@benbucksch
Copy link
Contributor

benbucksch commented Jun 25, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
awaiting submitter needs a reproduction, or clarification feature request popular more than 20 upthumbs temp-stale
Projects
None yet
Development

No branches or pull requests