#Solid-Start vinxi/http issue with useWebRequest

13 messages · Page 1 of 1 (latest)

echo parrot
#

Hey, when using getWebRequest from vinxi/http inside a Context I get the error,

Error: Module "node:async_hooks" has been externalized for browser compatibility. Cannot access "node:async_hooks.AsyncLocalStorage" in client code.

Here's the exact code that errors, I know it's getWebRequest as the error goes away after this.

import { createContext, createResource, createSignal, useContext } from 'solid-js';
import { isServer } from 'solid-js/web';
import { getUser } from '../utils/userUtils';
import { getWebRequest } from 'vinxi/http';

type UserDataType = [
  user: any,
]

const UserContext = createContext<UserDataType>();

export function UserProvider(props: any) {
  const [ user ] = createResource(fetchUser); const userData: UserDataType = [ user ];

  'use server';
  async function fetchUser() {
    if (!isServer) return;

    const request = getWebRequest();
    
    try {
      return await getUser(request);
    } catch (e) {
      console.log(e);

      return null;
    }
  }

  return (
    <UserContext.Provider value={userData}>
      {props.children}
    </UserContext.Provider>
  );
}

export function useUser() {
  return useContext(UserContext)!;
}
steady kernel
#

Put use server inside the function

#

Also i'd recommend moving fetchUser outside of UserProvider

echo parrot
#

Interesting, I figured "use server" applied to the thing below it, thanks.

Creates a new issue as it complains fetchUser now doesn't exist as it's only server-sided code but that makes sense, but I think I can just solve it by doing what you recommend by moving it outside the UserProvider component into the main app and just passing in my user via props instead to the context

#

Actually same issue persists, what's the correct way to handle this? I know it's from the use server part but how do I get the user using SSR along side a createResource, unless I should be using a different SSR fetching method?

ReferenceError: Cannot access 'fetchUser' before initialization

export default function App() {
  const [ user ] = createResource(fetchUser);

  async function fetchUser() {
    'use server';
    const request = getWebRequest();
    
    try {
      return await getUser(request);
    } catch (e) {
      console.log(e);

      return null;
    }
  }

  return (
    <>
      <Suspense>
        <UserProvider user={user}>
          <Home />
        </UserProvider>
      </Suspense>
    </>
  );
}
steady kernel
#

Move fetchUser outside App

#

Server functions definitions get hoisted up to the top of the module

echo parrot
#

That did fix it, do functions not hoist to the top?

echo parrot
steady kernel
#

The createServerReference that is codegened gets put to the top but the function implementation may not, which probably leads to that error

echo parrot
#

Ah

steady kernel
#

I think there's been talk of requiring all use server functions to be top level else just hard erroring to avoid situations like this

echo parrot
#

Yeah it would avoid confusion in cases like this, but it makes sense now that you explained why.