SolidJSS
SolidJS8mo ago
17 replies
Anshu

How to redirect from sub query

Hello there,
I'm trying to call a query within another query to avoid duplicate database calls. For example:

// This query is called in multiple places but will only run once and return data to all of them
const getRedirectOrUserQuery = query(async () => {
  "use server";
  const session = await getSession();
  const userId = session.data.userId;
  if (userId === undefined) throw redirect("/login");
  const user = await db.user.findUnique({ where: { id: userId } });
  if (!user) throw redirect("/register");
  return { id: user.id, username: user.username };
}, "get-redirect-or-user");

// Same logic, but as a server function instead of a query
const getRedirectOrUser = async () => {
  "use server";
  const session = await getSession();
  const userId = session.data.userId;
  if (userId === undefined) throw redirect("/login");
  const user = await db.user.findUnique({ where: { id: userId } });
  if (!user) throw redirect("/register");
  return { id: user.id, username: user.username };
};

// Main query used in createAsync
export const getUser = query(async () => {
  "use server";
  const user = await getRedirectOrUserQuery();
  return user;
}, "user");


The issue is that when the user is not found in the session or database, the getRedirectOrUserQuery function throws a redirect, but that exception is never received by getUser. Instead, getRedirectOrUserQuery returns
undefined
, and then getUser returns
undefined
.

If I look at the type of const user, it's inferred as non-nullable, but at runtime, it's actually
undefined
.

What I expect is for getRedirectOrUserQuery to throw a redirect, which should redirect the user and stop the execution of getUser.

Interestingly, if I replace the inner query call with a server function like this:

export const getUser = query(async () => {
  "use server";
  const user = await getRedirectOrUser();
  return user;
}, "user");


Then it works as expected.
Was this page helpful?