Cloud Flare Context is not defined when using Session

Im getting this message every time i try to call a server action that calls useSession hook
Uncaught (in promise) Error: Context is not available
Uncaught (in promise) Error: Context is not available
it only happens on CloudFlare preset builds. On preset cloudflare-modules the error is
SES_UNHANDLED_REJECTION: Error: Context is not available
SES_UNHANDLED_REJECTION: Error: Context is not available
import { useSession } from 'vinxi/http';

export interface UserSession {
id: number;
}

function getSession() {
'use server';
return useSession<UserSession>({
password: process.env.SESSION_SECRET!
});
}

export async function getSessionData() {
'use server';
const session = await getSession();
if (!session.data.id) {
return null;
}
return session.data;
}

export async function login() {
'use server';
const session = await getSession();
await session.update(() => ({
id: 1
}));

return session.data;
}

export async function logout() {
'use server';
const session = await getSession();
await session.clear();
}
import { useSession } from 'vinxi/http';

export interface UserSession {
id: number;
}

function getSession() {
'use server';
return useSession<UserSession>({
password: process.env.SESSION_SECRET!
});
}

export async function getSessionData() {
'use server';
const session = await getSession();
if (!session.data.id) {
return null;
}
return session.data;
}

export async function login() {
'use server';
const session = await getSession();
await session.update(() => ({
id: 1
}));

return session.data;
}

export async function logout() {
'use server';
const session = await getSession();
await session.clear();
}
No description
2 Replies
peerreynders
peerreynders8mo ago
Just a heads up; given that you say that this occurs inside an action (i.e. the response hasn't been created yet, so it couldn't have started streaming) it should not be relevant but FYI … useSession will always create (i.e. try to update) a session if there isn't one already which won't work if the response has already started streaming (this typically happens during SSR, not actions). The action itself may be helpful to provide "context" to whoever may be more knowledgeable about Cloudflare and its idiosyncrasies. Rubberduck out.
Rubber duck debugging
In software engineering, rubber duck debugging (or rubberducking) is a method of debugging code by articulating a problem in spoken or written natural language. The name is a reference to a story in the book The Pragmatic Programmer in which a programmer would carry around a rubber duck and debug their code by forcing themselves to explain it, l...
Costinha
CostinhaOP8mo ago
I refactored the code a bit, based on the "with-auth" template it is probably a Cloud Flare Wrangler issue since on node-server preset it works as expected the erros happens when trying to call login or logout here it is some code
export interface UserSession {
id?: number;
avatarUrl: string;
}

function getSession() {
'use server';
return useSession<UserSession>({
password: process.env.SESSION_SECRET!
});
}

export const getSessionData = cache(async () => {
'use server';
const session = await getSession();
if (!session.data.id) {
return null;
}
return session.data;
}, 'getSessionData');

export const login = action(async () => {
'use server';
const session = await getSession();
await session.update(() => ({
id: 1,
avatarUrl: '/public/profile.png'
}));

return revalidate('/');
});

export const logout = action(async () => {
'use server';
const session = await getSession();
await session.update(() => ({ id: undefined }));

return revalidate('/');
});
export interface UserSession {
id?: number;
avatarUrl: string;
}

function getSession() {
'use server';
return useSession<UserSession>({
password: process.env.SESSION_SECRET!
});
}

export const getSessionData = cache(async () => {
'use server';
const session = await getSession();
if (!session.data.id) {
return null;
}
return session.data;
}, 'getSessionData');

export const login = action(async () => {
'use server';
const session = await getSession();
await session.update(() => ({
id: 1,
avatarUrl: '/public/profile.png'
}));

return revalidate('/');
});

export const logout = action(async () => {
'use server';
const session = await getSession();
await session.update(() => ({ id: undefined }));

return revalidate('/');
});
export default function AvatarDropdown() {
const session = createAsync(() => getSessionData());

const doLogin = useAction(login);
const doLogout = useAction(logout);

return (
<DropdownMenu>
<DropdownMenuTrigger>
<Avatar class="size-9">
<AvatarImage alt="profile" src={session()?.avatarUrl} />
<AvatarFallback>CN</AvatarFallback>
<span class="sr-only">Toggle user menu</span>
</Avatar>
</DropdownMenuTrigger>
<DropdownMenuContent>
{!session() && (
<>
<DropdownMenuItem>
<span class="flex cursor-pointer items-center gap-2 text-lg" onClick={() => void doLogin()}>
<FiLogOut class="size-4" />
Login
</span>
</DropdownMenuItem>

<DropdownMenuSeparator />
</>
)}
<DropdownMenuItem>
<A class="flex items-center gap-2 text-lg" href="#">
<CgProfile class="size-4" />
Profile
</A>
</DropdownMenuItem>
<DropdownMenuItem>
<A class="flex items-center gap-2 text-lg" href="#">
<FiSettings class="size-4" />
Settings
</A>
</DropdownMenuItem>
<DropdownMenuSeparator />
{session() && (
<DropdownMenuItem>
<span class="flex cursor-pointer items-center gap-2 text-lg text-red-500" onClick={() => void doLogout()}>
<FiLogOut class="size-4" />
Logout
</span>
</DropdownMenuItem>
)}
</DropdownMenuContent>
</DropdownMenu>
);
}
export default function AvatarDropdown() {
const session = createAsync(() => getSessionData());

const doLogin = useAction(login);
const doLogout = useAction(logout);

return (
<DropdownMenu>
<DropdownMenuTrigger>
<Avatar class="size-9">
<AvatarImage alt="profile" src={session()?.avatarUrl} />
<AvatarFallback>CN</AvatarFallback>
<span class="sr-only">Toggle user menu</span>
</Avatar>
</DropdownMenuTrigger>
<DropdownMenuContent>
{!session() && (
<>
<DropdownMenuItem>
<span class="flex cursor-pointer items-center gap-2 text-lg" onClick={() => void doLogin()}>
<FiLogOut class="size-4" />
Login
</span>
</DropdownMenuItem>

<DropdownMenuSeparator />
</>
)}
<DropdownMenuItem>
<A class="flex items-center gap-2 text-lg" href="#">
<CgProfile class="size-4" />
Profile
</A>
</DropdownMenuItem>
<DropdownMenuItem>
<A class="flex items-center gap-2 text-lg" href="#">
<FiSettings class="size-4" />
Settings
</A>
</DropdownMenuItem>
<DropdownMenuSeparator />
{session() && (
<DropdownMenuItem>
<span class="flex cursor-pointer items-center gap-2 text-lg text-red-500" onClick={() => void doLogout()}>
<FiLogOut class="size-4" />
Logout
</span>
</DropdownMenuItem>
)}
</DropdownMenuContent>
</DropdownMenu>
);
}
Want results from more Discord servers?
Add your server