Skip to content

Commit f8c1123

Browse files
committed
enhance error logging and handling in various components for better debugging
Issue is resolved in fraud protection, other issues with serialization were red herrings. I am removing all code that does not contribute to the fix, but committing this here to ensure that I have a record of the error logging.
1 parent d7ed9c1 commit f8c1123

File tree

6 files changed

+176
-16
lines changed

6 files changed

+176
-16
lines changed

packages/clerk-js/src/core/clerk.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2754,14 +2754,40 @@ export class Clerk implements ClerkInterface {
27542754
Client.getOrCreateInstance().fetch({ fetchMaxTries }),
27552755
]);
27562756
} catch (err) {
2757+
// DEBUG: Log what error was caught
2758+
console.error('[Clerk] Caught error during initialization:', {
2759+
error: err,
2760+
errorType: typeof err,
2761+
errorMessage: err instanceof Error ? err.message : String(err),
2762+
errorCode: (err as any)?.code,
2763+
isClerkRuntimeError: isClerkRuntimeError(err),
2764+
hasCacheFunction: !!this.__internal_getCachedResources,
2765+
});
2766+
27572767
const isNetworkError =
27582768
(isClerkRuntimeError(err) && err.code === 'network_error') ||
27592769
(err instanceof Error && err.message?.includes('Network error at'));
27602770

2771+
console.error('[Clerk] Network error detection:', {
2772+
isNetworkError,
2773+
shouldFallback: this.shouldFallbackToCachedResources() && isNetworkError,
2774+
});
2775+
27612776
const shouldFallback = this.shouldFallbackToCachedResources() && isNetworkError;
27622777

27632778
if (shouldFallback) {
27642779
const cachedResources = await this.__internal_getCachedResources?.();
2780+
2781+
// DEBUG: Log cached resources before creating Environment
2782+
console.error('[Clerk] Creating Environment from cached resources:', {
2783+
hasCachedResources: !!cachedResources,
2784+
hasEnvironment: !!cachedResources?.environment,
2785+
environmentKeys: cachedResources?.environment ? Object.keys(cachedResources.environment) : 'N/A',
2786+
hasProtectConfig: cachedResources?.environment ? 'protect_config' in cachedResources.environment : 'N/A',
2787+
protectConfigValue: cachedResources?.environment?.protect_config,
2788+
protectConfigType: cachedResources?.environment ? typeof cachedResources.environment.protect_config : 'N/A',
2789+
});
2790+
27652791
environment = new Environment(cachedResources?.environment);
27662792
Client.clearInstance();
27672793
client = Client.getOrCreateInstance(cachedResources?.client);

packages/clerk-js/src/core/fraudProtection.ts

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ClerkRuntimeError, isClerkAPIResponseError } from '@clerk/shared/error';
1+
import { ClerkRuntimeError, isClerkAPIResponseError, isClerkRuntimeError } from '@clerk/shared/error';
22

33
import { CaptchaChallenge } from '../utils/captcha/CaptchaChallenge';
44
import type { Clerk } from './resources/internal';
@@ -26,6 +26,7 @@ export class FraudProtection {
2626

2727
// TODO @userland-errors:
2828
public async execute<T extends () => Promise<any>, R = Awaited<ReturnType<T>>>(clerk: Clerk, cb: T): Promise<R> {
29+
console.error('[FraudProtection] execute() called');
2930
// TODO @userland-errors:
3031
if (this.captchaAttemptsExceeded()) {
3132
throw new ClerkRuntimeError(
@@ -39,12 +40,28 @@ export class FraudProtection {
3940
await this.inflightException;
4041
}
4142

42-
return await cb();
43+
console.error('[FraudProtection] About to execute callback');
44+
const result = await cb();
45+
console.error('[FraudProtection] Callback executed successfully');
46+
return result;
4347
} catch (e) {
48+
console.error('[FraudProtection] Callback threw error:', {
49+
error: e,
50+
errorType: typeof e,
51+
errorMessage: e instanceof Error ? e.message : String(e),
52+
isClerkAPIResponseError: isClerkAPIResponseError(e),
53+
});
4454
if (!isClerkAPIResponseError(e)) {
4555
throw e;
4656
}
4757

58+
// Network errors should bypass captcha logic and be re-thrown immediately
59+
// so cache fallback can be triggered
60+
if (isClerkRuntimeError(e) && e.code === 'network_error') {
61+
console.error('[FraudProtection] Re-throwing network error for cache fallback');
62+
throw e;
63+
}
64+
4865
if (e.errors[0]?.code !== 'requires_captcha') {
4966
throw e;
5067
}

packages/clerk-js/src/core/resources/Environment.ts

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,79 @@ export class Environment extends BaseResource implements EnvironmentResource {
4747
return this;
4848
}
4949

50-
this.authConfig = new AuthConfig(data.auth_config);
51-
this.displayConfig = new DisplayConfig(data.display_config);
50+
// DEBUG: Log environment data structure
51+
console.error('[Environment fromJSON] Processing environment data:', {
52+
hasProtectConfig: 'protect_config' in data,
53+
protectConfigValue: data.protect_config,
54+
protectConfigType: typeof data.protect_config,
55+
dataKeys: Object.keys(data),
56+
});
57+
58+
try {
59+
console.error('[Environment fromJSON] Creating AuthConfig...');
60+
this.authConfig = new AuthConfig(data.auth_config);
61+
console.error('[Environment fromJSON] ✓ AuthConfig created successfully');
62+
} catch (err) {
63+
console.error('[Environment fromJSON] ✗ AuthConfig FAILED:', err);
64+
throw err;
65+
}
66+
67+
try {
68+
console.error('[Environment fromJSON] Creating DisplayConfig...');
69+
this.displayConfig = new DisplayConfig(data.display_config);
70+
console.error('[Environment fromJSON] ✓ DisplayConfig created successfully');
71+
} catch (err) {
72+
console.error('[Environment fromJSON] ✗ DisplayConfig FAILED:', err);
73+
throw err;
74+
}
75+
5276
this.maintenanceMode = this.withDefault(data.maintenance_mode, this.maintenanceMode);
5377
this.clientDebugMode = this.withDefault(data.client_debug_mode, this.clientDebugMode);
54-
this.organizationSettings = new OrganizationSettings(data.organization_settings);
55-
this.userSettings = new UserSettings(data.user_settings);
56-
this.commerceSettings = new CommerceSettings(data.commerce_settings);
57-
this.apiKeysSettings = new APIKeySettings(data.api_keys_settings);
58-
this.protectConfig = new ProtectConfig(data.protect_config);
78+
79+
try {
80+
console.error('[Environment fromJSON] Creating OrganizationSettings...');
81+
this.organizationSettings = new OrganizationSettings(data.organization_settings);
82+
console.error('[Environment fromJSON] ✓ OrganizationSettings created successfully');
83+
} catch (err) {
84+
console.error('[Environment fromJSON] ✗ OrganizationSettings FAILED:', err);
85+
throw err;
86+
}
87+
88+
try {
89+
console.error('[Environment fromJSON] Creating UserSettings...');
90+
this.userSettings = new UserSettings(data.user_settings);
91+
console.error('[Environment fromJSON] ✓ UserSettings created successfully');
92+
} catch (err) {
93+
console.error('[Environment fromJSON] ✗ UserSettings FAILED:', err);
94+
throw err;
95+
}
96+
97+
try {
98+
console.error('[Environment fromJSON] Creating CommerceSettings...');
99+
this.commerceSettings = new CommerceSettings(data.commerce_settings);
100+
console.error('[Environment fromJSON] ✓ CommerceSettings created successfully');
101+
} catch (err) {
102+
console.error('[Environment fromJSON] ✗ CommerceSettings FAILED:', err);
103+
throw err;
104+
}
105+
106+
try {
107+
console.error('[Environment fromJSON] Creating APIKeySettings...');
108+
this.apiKeysSettings = new APIKeySettings(data.api_keys_settings);
109+
console.error('[Environment fromJSON] ✓ APIKeySettings created successfully');
110+
} catch (err) {
111+
console.error('[Environment fromJSON] ✗ APIKeySettings FAILED:', err);
112+
throw err;
113+
}
114+
115+
try {
116+
console.error('[Environment fromJSON] Creating ProtectConfig with:', data.protect_config);
117+
this.protectConfig = new ProtectConfig(data.protect_config);
118+
console.error('[Environment fromJSON] ✓ ProtectConfig created successfully');
119+
} catch (err) {
120+
console.error('[Environment fromJSON] ✗ ProtectConfig FAILED:', err);
121+
throw err;
122+
}
59123

60124
return this;
61125
}

packages/clerk-js/src/core/resources/ProtectConfig.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,24 @@ export class ProtectConfig extends BaseResource implements ProtectConfigResource
1515
public constructor(data: ProtectConfigJSON | ProtectConfigJSONSnapshot | null = null) {
1616
super();
1717

18+
// DEBUG: Log what data is received
19+
console.error('[ProtectConfig Constructor] Received data:', {
20+
data,
21+
dataType: typeof data,
22+
isNull: data === null,
23+
isUndefined: data === undefined,
24+
keys: data ? Object.keys(data) : 'N/A',
25+
});
26+
1827
this.fromJSON(data);
1928
}
2029

2130
protected fromJSON(data: ProtectConfigJSON | ProtectConfigJSONSnapshot | null): this {
2231
if (!data) {
32+
console.error('[ProtectConfig fromJSON] Data is falsy, returning early:', {
33+
data,
34+
dataType: typeof data,
35+
});
2336
return this;
2437
}
2538

packages/clerk-js/src/core/resources/UserSettings.ts

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -203,16 +203,37 @@ export class UserSettings extends BaseResource implements UserSettingsResource {
203203
}
204204

205205
protected fromJSON(data: UserSettingsJSON | UserSettingsJSONSnapshot | null): this {
206+
console.error('[UserSettings fromJSON] Called with:', {
207+
hasData: !!data,
208+
dataKeys: data ? Object.keys(data) : 'null',
209+
hasAttributes: data ? 'attributes' in data : false,
210+
attributesValue: data ? data.attributes : 'N/A',
211+
attributesType: data ? typeof data.attributes : 'N/A',
212+
});
213+
206214
if (!data) {
207215
return this;
208216
}
209217

210-
this.attributes = this.withDefault(
211-
data.attributes
212-
? (Object.fromEntries(Object.entries(data.attributes).map(a => [a[0], { ...a[1], name: a[0] }])) as Attributes)
213-
: null,
214-
this.attributes,
215-
);
218+
try {
219+
console.error('[UserSettings fromJSON] About to process attributes');
220+
this.attributes = this.withDefault(
221+
data.attributes
222+
? (Object.fromEntries(
223+
Object.entries(data.attributes).map(a => [a[0], { ...a[1], name: a[0] }]),
224+
) as Attributes)
225+
: null,
226+
this.attributes,
227+
);
228+
console.error('[UserSettings fromJSON] ✓ Attributes processed successfully');
229+
} catch (err) {
230+
console.error('[UserSettings fromJSON] ✗ FAILED processing attributes:', {
231+
error: err,
232+
errorMessage: err instanceof Error ? err.message : String(err),
233+
dataAttributes: data.attributes,
234+
});
235+
throw err;
236+
}
216237
this.actions = this.withDefault(data.actions, this.actions);
217238
this.enterpriseSSO = this.withDefault(data.enterprise_sso, this.enterpriseSSO);
218239
this.passkeySettings = this.withDefault(data.passkey_settings, this.passkeySettings);

packages/expo/src/provider/singleton/createClerkInstance.ts

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,14 @@ export function createClerkInstance(ClerkClass: typeof Clerk) {
118118
// @ts-expect-error - This is an internal API
119119
const environment = __internal_clerk?.__unstable__environment as EnvironmentResource;
120120
if (environment) {
121-
void EnvironmentResourceCache.save(environment.__internal_toSnapshot());
121+
const snapshot = environment.__internal_toSnapshot();
122+
// DEBUG: Log what we're saving to cache
123+
console.error('[Cache Save] Saving environment snapshot:', {
124+
hasProtectConfig: 'protect_config' in snapshot,
125+
protectConfigValue: snapshot.protect_config,
126+
snapshotKeys: Object.keys(snapshot),
127+
});
128+
void EnvironmentResourceCache.save(snapshot);
122129
}
123130

124131
if (client) {
@@ -141,7 +148,19 @@ export function createClerkInstance(ClerkClass: typeof Clerk) {
141148
}> => {
142149
let environment = await EnvironmentResourceCache.load();
143150
let client = await ClientResourceCache.load();
151+
152+
// DEBUG: Log cached data structure
153+
console.error('[Cache Load] Loaded from cache:', {
154+
hasEnvironment: !!environment,
155+
hasClient: !!client,
156+
environmentKeys: environment ? Object.keys(environment) : 'null',
157+
hasProtectConfigInCache: environment ? 'protect_config' in environment : 'N/A',
158+
protectConfigValue: environment ? environment.protect_config : 'N/A',
159+
protectConfigType: environment ? typeof environment.protect_config : 'N/A',
160+
});
161+
144162
if (!environment || !client) {
163+
console.error('[Cache Load] Using DUMMY data - cache was empty or incomplete');
145164
environment = DUMMY_CLERK_ENVIRONMENT_RESOURCE;
146165
client = DUMMY_CLERK_CLIENT_RESOURCE;
147166
setTimeout(() => void retryInitilizeResourcesFromFAPI(), 3000);

0 commit comments

Comments
 (0)