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

Error thrown from beforeLoad and handled through errorComponent is ignored on initial request #3462

Open
KiwiKilian opened this issue Feb 17, 2025 · 3 comments

Comments

@KiwiKilian
Copy link

Which project does this relate to?

Start

Describe the bug

When an error is thrown from beforeLoad and handled througherrorComponent it only works as expected on client navigation. When the page is reloaded/first requested the return for errorComponent is ignored and component/rest of the tree is rendered. This breaks many auth setups currently.

Your Example Website or App

https://tanstack.com/start/latest/docs/framework/react/examples/start-basic-auth

Steps to Reproduce the Bug or Issue

This can be reproduced using the Start Basic Auth example.

  1. Navigate to "Posts" – the login is shown ✅
  2. Now reload the "Posts" page – error is shown instead of login ❌

This error is shown:

posts is not iterable

You can also add a console.log to app/routes/_authed/posts.tsx. This shows it tries to render the component, even though we are still unauthenticated and beforeLoad in app/routes/_authed.tsx throws an error which is handled by errorComponent, which should prevent rendering of the posts/component.

Expected behavior

When throwing an error from beforeLoad and handling it within errorComponent the component should not be rendered – even on intial request handled by the server without client side navigation.

Screenshots or Videos

start-before-load-error-component.mp4

Platform

  • OS: macOS
  • Browser: Chromium
  • Version: 133

Additional context

No response

@rgarcia
Copy link

rgarcia commented Feb 19, 2025

any good workaround? This makes all URLs behind a login wall throw an error which is not ideal....

@Grimthul
Copy link

Having the exact same issue. It happens even on more trivial case, where I try to redirect in beforeLoad function.

export const Route = createFileRoute("/_auth")({
    beforeLoad: ({ context }) => {
        console.log("auth before load", context, !context.user);
        if (!context.user) {
            throw redirect({ to: "/login", search: { redirect: location.href } });
        }
    },
});

Even when the user is null, it does not redirect but goes directly to the page that should be under authentication.
Also it logs Hydration failed errors to the console.

@Grimthul
Copy link

One more thing, in the demo, when I try to change the beforeLoad function in _authed:

export const Route = createFileRoute('/_authed')({
  beforeLoad: ({ context }) => {
    if (!context.user) {
      throw new Error('Not authenticated')
    }
  },
  errorComponent: ({ error }) => {
    if (error.message === 'Not authenticated') {
      return <Login />
    }

    throw error
  },
})

to loader function:

export const Route = createFileRoute("/_authed")({
  loader: ({ context }) => {
    if (!context.user) {
      throw new Error("Not authenticated");
    }
  },
  errorComponent: ({ error }) => {
    if (error.message === "Not authenticated") {
      return <Login />;
    }

    throw error;
  },
});

It works almost properly - atleast from user point of view, he will get the login component as he should.
BUT there is another problem, it requests ServerFn Request: app_utils_posts_ts--fetchPosts_createServerFn_handler
which should not be called, it should not be fetching posts if the user is not signed in.

I know documentation recommends using the beforeLoad function and not the loader, just wanted to provide additional info to find the cause as it is really bad bug, breaking auth functionality.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants