diff --git a/.changeset/every-chefs-mix.md b/.changeset/every-chefs-mix.md new file mode 100644 index 00000000000..012b67a0644 --- /dev/null +++ b/.changeset/every-chefs-mix.md @@ -0,0 +1,5 @@ +--- +'@clerk/clerk-js': patch +--- + +Add debug logging to session update flows when browser is offline diff --git a/packages/clerk-js/src/core/auth/AuthCookieService.ts b/packages/clerk-js/src/core/auth/AuthCookieService.ts index 7237c61c45d..51268dc6bcd 100644 --- a/packages/clerk-js/src/core/auth/AuthCookieService.ts +++ b/packages/clerk-js/src/core/auth/AuthCookieService.ts @@ -1,3 +1,4 @@ +import { isValidBrowserOnline } from '@clerk/shared/browser'; import type { createClerkEventBus } from '@clerk/shared/clerkEventBus'; import { clerkEvents } from '@clerk/shared/clerkEventBus'; import type { createCookieHandler } from '@clerk/shared/cookie'; @@ -6,6 +7,8 @@ import { is4xxError, isClerkAPIResponseError, isClerkRuntimeError, isNetworkErro import type { Clerk, InstanceType } from '@clerk/shared/types'; import { noop } from '@clerk/shared/utils'; +import { debugLogger } from '@/utils/debug'; + import { clerkMissingDevBrowserJwt } from '../errors'; import { eventBus, events } from '../events'; import type { FapiClient } from '../fapiClient'; @@ -174,6 +177,10 @@ export class AuthCookieService { return; } + if (!token && !isValidBrowserOnline()) { + debugLogger.warn('Removing session cookie (offline)', { sessionId: this.clerk.session?.id }, 'authCookieService'); + } + this.setActiveContextInStorage(); return token ? this.sessionCookie.set(token) : this.sessionCookie.remove(); diff --git a/packages/clerk-js/src/core/clerk.ts b/packages/clerk-js/src/core/clerk.ts index 75d2a2b28c7..1d9f44f5258 100644 --- a/packages/clerk-js/src/core/clerk.ts +++ b/packages/clerk-js/src/core/clerk.ts @@ -1380,6 +1380,13 @@ export class Clerk implements ClerkInterface { // getToken syncs __session and __client_uat to cookies using events.TokenUpdate dispatched event. const token = await newSession?.getToken(); if (!token) { + if (!isValidBrowserOnline()) { + debugLogger.warn( + 'Token is null when setting active session (offline)', + { sessionId: newSession?.id }, + 'clerk', + ); + } eventBus.emit(events.TokenUpdate, { token: null }); } @@ -2380,6 +2387,13 @@ export class Clerk implements ClerkInterface { this.#setAccessors(session); // A client response contains its associated sessions, along with a fresh token, so we dispatch a token update event. + if (!this.session?.lastActiveToken && !isValidBrowserOnline()) { + debugLogger.warn( + 'No last active token when updating client (offline)', + { sessionId: this.session?.id }, + 'clerk', + ); + } eventBus.emit(events.TokenUpdate, { token: this.session?.lastActiveToken }); } diff --git a/packages/clerk-js/src/core/resources/Base.ts b/packages/clerk-js/src/core/resources/Base.ts index a7d1461aa10..cc1b5db9819 100644 --- a/packages/clerk-js/src/core/resources/Base.ts +++ b/packages/clerk-js/src/core/resources/Base.ts @@ -8,6 +8,8 @@ import type { DeletedObjectJSON, } from '@clerk/shared/types'; +import { debugLogger } from '@/utils/debug'; + import { clerkMissingFapiClientInResources } from '../errors'; import type { FapiClient, FapiRequestInit, FapiResponse, FapiResponseJSON, HTTPMethod } from '../fapiClient'; import { FraudProtection } from '../fraudProtection'; @@ -98,7 +100,14 @@ export abstract class BaseResource { code: 'network_error', }); } else if (!isValidBrowserOnline()) { - console.warn(e); + debugLogger.warn( + 'Network request failed while offline, returning null', + { + method: requestInit.method, + path: requestInit.path, + }, + 'baseResource', + ); return null; } else { throw e; diff --git a/packages/clerk-js/src/core/resources/__tests__/Token.test.ts b/packages/clerk-js/src/core/resources/__tests__/Token.test.ts index 066f10b907f..aed2f6f2863 100644 --- a/packages/clerk-js/src/core/resources/__tests__/Token.test.ts +++ b/packages/clerk-js/src/core/resources/__tests__/Token.test.ts @@ -2,6 +2,7 @@ import type { InstanceType } from '@clerk/shared/types'; import { afterEach, beforeEach, describe, expect, it, type Mock, vi } from 'vitest'; import { mockFetch, mockNetworkFailedFetch } from '@/test/core-fixtures'; +import { debugLogger } from '@/utils/debug'; import { SUPPORTED_FAPI_VERSION } from '../../constants'; import { createFapiClient } from '../../fapiClient'; @@ -50,7 +51,7 @@ describe('Token', () => { writable: true, value: false, }); - warnSpy = vi.spyOn(console, 'warn').mockReturnValue(); + warnSpy = vi.spyOn(debugLogger, 'warn').mockReturnValue(); }); afterEach(() => {