@@ -5,6 +5,7 @@ import {
|
||||
} from "@tanstack/react-query";
|
||||
import { toast } from "sonner-native";
|
||||
import { ApiError, logError, reportError, toUserMessage } from "@/lib/errors";
|
||||
import { useAuthStore } from "@/stores/auth-store";
|
||||
|
||||
declare module "@tanstack/react-query" {
|
||||
interface Register {
|
||||
@@ -22,6 +23,16 @@ function shouldRetryQuery(failureCount: number, err: unknown): boolean {
|
||||
return failureCount < 2;
|
||||
}
|
||||
|
||||
// A 401 surfaced through react-query means the server rejected our bearer
|
||||
// token. This is the *only* place that turns that into an auth state change —
|
||||
// the apiClient is a dumb transport. Direct apiClient callers (signIn,
|
||||
// restoreSession, signInToFirebase) handle their own 401s explicitly.
|
||||
function handleUnauthorized(err: unknown): void {
|
||||
if (err instanceof ApiError && err.status === 401) {
|
||||
void useAuthStore.getState().invalidateSession();
|
||||
}
|
||||
}
|
||||
|
||||
export function createQueryClient(): QueryClient {
|
||||
return new QueryClient({
|
||||
defaultOptions: {
|
||||
@@ -36,6 +47,7 @@ export function createQueryClient(): QueryClient {
|
||||
},
|
||||
queryCache: new QueryCache({
|
||||
onError: (err, query) => {
|
||||
handleUnauthorized(err);
|
||||
logError(err, { scope: "query", queryKey: query.queryKey });
|
||||
if (query.meta?.toastOnError) {
|
||||
toast.error(toUserMessage(err));
|
||||
@@ -44,6 +56,7 @@ export function createQueryClient(): QueryClient {
|
||||
}),
|
||||
mutationCache: new MutationCache({
|
||||
onError: (err, _variables, _context, mutation) => {
|
||||
handleUnauthorized(err);
|
||||
reportError(err, {
|
||||
scope: "mutation",
|
||||
mutationKey: mutation.options.mutationKey,
|
||||
|
||||
Reference in New Issue
Block a user