solidjs/solid-router

Routing breaks if a route component's root is a `<Show>` for a rejected resource

Closed this issue · 6 comments

Describe the bug

In the Stackblitz, a component uses <Show> to only show content once a resource has loaded. If that resource's Promise rejects, all routes cannot render anymore. Navigation will invoke a component function, but its body is never displayed.

Your Example Website or App

https://stackblitz.com/edit/solidjs-templates-eebkn9?file=src%2Findex.tsx

Steps to Reproduce the Bug or Issue

  1. Create a resource which rejects
  2. Write a component whose top-level element is <Show when={thatResource()}>...

If the <Show> is wrapped in a <div>, this issue does not reproduce.

Expected behavior

I can still navigate to other routes like normal

Screenshots or Videos

No response

Platform

  • OS: Linux
  • Browser: Vivaldi, Firefox
  • Version: Vivaldi 6.8.3381.57

Additional context

No response

We throw errors on read with resources. We don't error on fetch. The mechanism similar to Suspense is based around whether or not we are able to render with what we have. So if there isn't an ErrorBoundary that is expected.

Ah, I see that adding an ErrorBoundary does keep things from breaking.

Just to confirm:

  1. In the absence of an ErrorBoundary, we expect a failed resource read in <Show /> to permanently break rendering for the whole router.
  2. We expect (1) to behave differently for <Show /> vs <div><Show /></div>.

Is that right?

  1. Yes, it's an unhandled/uncaught error we can't predict what will happen.
  2. No I would not expect div wrapper to change this.

It doesn't right? I just added a div and it looks broken still to me.

It doesn't right? I just added a div and it looks broken still to me.

Ah, pardon my lack of specificity. When I alter the sandbox to wrap the MyBadComponent's <Show> in a div, MyBadComponent is still broken, but the routing behavior changes from "the whole router is broken permanently" to "only this route broken, but you can still navigate away to other routes".

Altered sandbox

But it sounds like it doesn't really matter either way? Since a <Show> that reads a rejected resource without an ErrorBoundary is undefined behavior?

Would it make sense for Solid to emit a console warning when reading resources without an ErrorBoundary ancestor?

Would it make sense for Solid to emit a console warning when reading resources without an ErrorBoundary ancestor?

Maybe.. but it doesn't really know that until you throw an error. We could do an additioanl context lookup at the time of read in dev or something I suppose. It is interesting what sort of ways we could indicate to the developer better patterns.

I think this is more general future question though. I think we will leave this one right now as is because there isn't anything that will get fixed. I agree the inconsistency is not good but the whole behavior falls within undefined behavior (ie an error is thrown and not caught). But in any case a change won't be in the router but a more core question.