Throwing or returning in redirect inside a cache function used in load results in error
Describe the bug
Given this code:
import { Title } from '@solidjs/meta';
import { RouteDefinition, cache, redirect } from '@solidjs/router';
import Counter from '~/components/Counter';
let isLoggedIn = false;
const redirectIfNotLoggedIn = cache(() => {
if (!isLoggedIn) throw redirect('/login');
return { data: 'test' };
}, 'redirect-if-not-logged-in');
export const route: RouteDefinition = {
load: async () => await redirectIfNotLoggedIn(),
};
export default function Home() {
return (
<main>
<Title>Hello World</Title>
<h1>Hello world!</h1>
<Counter />
<p>
Visit{' '}
<a href="https://start.solidjs.com" target="_blank">
start.solidjs.com
</a>{' '}
to learn how to build SolidStart apps.
</p>
</main>
);
}
When returning a redirect from a cache function, this error occurs:
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at __node_internal_captureLargerStackTrace2 (https://yqniqqmaogithub-cd2c.w-corp-staticblitz.com/builtins.5bf3667c.js:101:5335)
at new NodeError (https://yqniqqmaogithub-cd2c.w-corp-staticblitz.com/builtins.5bf3667c.js:101:4149)
at ServerResponse.setHeader (https://yqniqqmaogithub-cd2c.w-corp-staticblitz.com/builtins.5bf3667c.js:6:8796)
at setResponseHeader (file:///home/projects/yqniqqmao.github/node_modules/h3/dist/index.mjs:908:18)
at Module.eval (/home/projects/yqniqqmao.github/node_modules/vinxi/runtime/http.js:149:12)
at eval (/home/projects/yqniqqmao.github/node_modules/@solidjs/start/dist/server/handler.js:101:29)
at doShell (file:///home/projects/yqniqqmao.github/node_modules/solid-js/web/dist/server.js:358:7)
at Object.onDone (file:///home/projects/yqniqqmao.github/node_modules/solid-js/web/dist/server.js:221:5)
at Te.flush (file:///home/projects/yqniqqmao.github/node_modules/seroval/dist/esm/production/index.mjs:61:38999)
at eval (file:///home/projects/yqniqqmao.github/node_modules/solid-js/web/dist/server.js:240:42) {
code: 'ERR_HTTP_HEADERS_SENT'
}
Node.js 18.20.3
When throwing a redirect:
[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "[object Response]".] {
code: 'ERR_UNHANDLED_REJECTION'
}
Node.js 18.20.3
Your Example Website or App
https://stackblitz.com/edit/github-3nqamc?file=src%2Froutes%2Findex.tsx
Steps to Reproduce the Bug or Issue
- Run the application
- Visit the index route
Expected behavior
Returning/throwing a redirect in a cache function should redirect
Screenshots or Videos
No response
Platform
- OS: Fedora Linux
- Browser: Edge
Additional context
No response
Likely it's because the server has already responded at the point that it resolves. If there is no async in your components then the server is going to thing it is done (or at least can stream the first chunk).. in which case by the time it tries to process the redirect it thinks it is done. There might be still a timing bug/missing guard here but we probably need to find a reproduction that reads the routes data.
I'm going to move this to SolidStart because if there is an issue it makes sense to fix it is there.