frontarm / navi

🧭 Declarative, asynchronous routing for React.
https://frontarm.com/navi/
MIT License
2.07k stars 71 forks source link

Throw 404 error from the client side #138

Closed DB-Alex closed 5 years ago

DB-Alex commented 5 years ago

Hi,

Is it possible to throw a 404 error from the client side?

I was trying something like this:

throw new NotFoundError(request.originalUrl);

But the NotFoundBoundary does not come up.

jamesknelson commented 5 years ago

It should be possible to import NotFoundBoundary from Navi and throw that, as it's exported. If you do this from within a component, then the boundary should be triggered.

Where are you throwing the error from?

DB-Alex commented 5 years ago

I have a multi language app so in my router I have:

'/how-it-works': withLocale({
            'en': lazy(() => import('pages/HowItWorksPage')),
            'nl': redirect('/werkwijze/'),
        }),

Now when someone tries the access this route with locale de there is no route so it should throw a 404.

const withLocale = (matchers) => {
    return map((request, context) => {
        if (matchers[context.locale]) {
            return matchers[context.locale];
        }

        // Throw 404 when nothing found for current locale
        throw new NotFoundError(request.originalUrl);
    });
};

The NotFoundBoundary is already in my I just need it to be triggered so it shows the 404 page.

jamesknelson commented 5 years ago

Hmm... I would have thought this would triggered the 404 page already.

Is the component with the NotFoundBoundary rendered in the root view?

DB-Alex commented 5 years ago

The NotFoundBoundary is in my App component and in routes.js I have:

export default compose(
    withView((request, context) =>
        <App
            currentUser={context.currentUser}
            appLocale={context.locale}
        />,
    ),
jamesknelson commented 5 years ago

Okay. And just to check, the <App /> component has a <View /> inside it?

Is there any chance you could get a minimal reproduction on working on CodeSandbox or similar?

DB-Alex commented 5 years ago

This is inside app render:

<div className={classes['root']}>
                                        <BottomMenu />
                                        <MobileWrapper>
                                            <Header />
                                            <Main theme={theme}>
                                                <NotFoundBoundary render={NotFound}>
                                                    <View />
                                                </NotFoundBoundary>
                                            </Main>
                                            <Footer theme={theme} />
                                            <LiveChat />
                                        </MobileWrapper>
                                    </div>
DB-Alex commented 5 years ago

I fixed it:

<NotFoundBoundary render={NotFound}>

Needed to be:

<NotFoundBoundary
                                                    render={() => (
                                                        <NotFound />
                                                    )}
                                                >