Merge pull request 'more auth ree' (#13) from development into main
All checks were successful
CI/CD Pipeline / Build and Push App Docker Image (push) Successful in 2m38s
CI/CD Pipeline / Build and Push PocketBase Docker Image (push) Successful in 8s
CI/CD Pipeline / Deploy to Kubernetes (push) Successful in 43s

Reviewed-on: #13
This commit is contained in:
2026-03-02 22:17:35 -06:00
5 changed files with 50 additions and 7 deletions

View File

@@ -127,6 +127,11 @@ export const Route = createRootRouteWithContext<{
return { auth }; return { auth };
} catch (error: any) { } catch (error: any) {
if (error?.options?.to && error?.options?.statusCode) {
console.log('__root beforeLoad: Re-throwing redirect', error.options);
throw error;
}
console.error('__root beforeLoad error:', error); console.error('__root beforeLoad error:', error);
return {}; return {};
} }

View File

@@ -15,7 +15,7 @@ export const fetchMe = createServerFn()
const request = getRequest(); const request = getRequest();
try { try {
const context = await getSessionContext(request); const context = await getSessionContext(request, { isServerFunction: true });
await pbAdmin.authPromise; await pbAdmin.authPromise;
const result = await pbAdmin.getPlayerByAuthId(context.userAuthId); const result = await pbAdmin.getPlayerByAuthId(context.userAuthId);
@@ -55,6 +55,24 @@ export const fetchMe = createServerFn()
} }
} }
if (error?.message === "SESSION_REFRESH_REQUIRED") {
logger.info("FetchMe: Session refresh required (server function)");
throw new Response(
JSON.stringify({
error: "SESSION_REFRESH_REQUIRED",
message: "Session needs to be refreshed",
shouldRetry: true
}),
{
status: 440,
headers: {
"Content-Type": "application/json",
"X-Session-Expired": "true"
}
}
);
}
if (error?.message === "Unauthenticated") { if (error?.message === "Unauthenticated") {
logger.info("FetchMe: No authenticated user (expected when not logged in)"); logger.info("FetchMe: No authenticated user (expected when not logged in)");
return { user: undefined, roles: [], metadata: {}, phone: undefined }; return { user: undefined, roles: [], metadata: {}, phone: undefined };

View File

@@ -11,13 +11,20 @@ export async function ensureServerQueryData<TData>(
return queryClient.ensureQueryData({ return queryClient.ensureQueryData({
queryKey: query.queryKey, queryKey: query.queryKey,
queryFn: async () => { queryFn: async () => {
const result = await query.queryFn(); try {
const result = await query.queryFn();
if (!result.success) {
throw new Error(result.error.userMessage); if (!result.success) {
throw new Error(result.error.userMessage);
}
return result.data;
} catch (error: any) {
if (error?.options?.to && error?.options?.statusCode) {
throw error;
}
throw error;
} }
return result.data;
} }
}); });
} }

View File

@@ -10,6 +10,11 @@ export async function handleQueryError(error: any): Promise<void> {
throw error; throw error;
} }
if (error.options?.to && error.options?.statusCode) {
logger.info('handleQueryError: Re-throwing TanStack Router redirect', error.options);
throw error;
}
if (error instanceof Response) { if (error instanceof Response) {
const status = error.status; const status = error.status;

View File

@@ -26,6 +26,14 @@ export const toServerResult = async <T>(
const data = await serverFn(); const data = await serverFn();
return { success: true, data }; return { success: true, data };
} catch (error) { } catch (error) {
if (error && typeof error === 'object' && 'options' in error) {
const redirectError = error as any;
if (redirectError.options?.to && redirectError.options?.statusCode) {
logger.info('toServerResult: Re-throwing TanStack Router redirect', redirectError.options);
throw error;
}
}
const duration = Date.now() - startTime; const duration = Date.now() - startTime;
logger.error('Server Fn Error', error); logger.error('Server Fn Error', error);