From 622b062b23afbd11703c6bb14a3dfabdc2c5f390 Mon Sep 17 00:00:00 2001 From: Jacek Date: Wed, 5 Nov 2025 22:10:48 -0600 Subject: [PATCH 1/4] fix: local integration tests --- integration/models/application.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/integration/models/application.ts b/integration/models/application.ts index c8a6b2df2aa..e3593c3f594 100644 --- a/integration/models/application.ts +++ b/integration/models/application.ts @@ -92,6 +92,11 @@ export const application = ( buildOutput += `\n${msg}`; log(msg); }, + // Only ignore stdio locally to work around Next.js .Trash folder EPERM errors on macOS. + // In CI we want to see the full build output for debugging. + // See https://github.com/vercel/next.js/issues/60334 + // eslint-disable-next-line turbo/no-undeclared-env-vars + stdio: process.env.CI ? undefined : 'ignore', }); }, get buildOutput() { From 012f867913dcbdc1626801b81877db27d37af547 Mon Sep 17 00:00:00 2001 From: Jacek Date: Wed, 5 Nov 2025 22:19:44 -0600 Subject: [PATCH 2/4] wip --- integration/testUtils/usersService.ts | 37 +++++++++++++++++++-------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/integration/testUtils/usersService.ts b/integration/testUtils/usersService.ts index a95114a6fb7..ba7b8c17d82 100644 --- a/integration/testUtils/usersService.ts +++ b/integration/testUtils/usersService.ts @@ -125,15 +125,30 @@ export const createUserService = (clerkClient: ClerkClient) => { }; }, createBapiUser: async fakeUser => { - return await clerkClient.users.createUser({ - emailAddress: fakeUser.email !== undefined ? [fakeUser.email] : undefined, - password: fakeUser.password, - firstName: fakeUser.firstName, - lastName: fakeUser.lastName, - phoneNumber: fakeUser.phoneNumber !== undefined ? [fakeUser.phoneNumber] : undefined, - username: fakeUser.username, - skipPasswordRequirement: fakeUser.password === undefined, - }); + try { + return await clerkClient.users.createUser({ + emailAddress: fakeUser.email !== undefined ? [fakeUser.email] : undefined, + firstName: fakeUser.firstName, + lastName: fakeUser.lastName, + password: fakeUser.password, + phoneNumber: fakeUser.phoneNumber !== undefined ? [fakeUser.phoneNumber] : undefined, + skipPasswordRequirement: fakeUser.password === undefined, + username: fakeUser.username, + }); + } catch (error: any) { + if (error?.status === 429) { + const details = [ + `Retry-After: ${error.retryAfter ?? 'not provided'} seconds`, + error.clerkTraceId ? `Trace ID: ${error.clerkTraceId}` : null, + error.errors?.length > 0 ? `API Errors: ${error.errors.map((e: any) => e.message).join(', ')}` : null, + ] + .filter(Boolean) + .join(' | '); + + throw new Error(`Rate limit exceeded (HTTP 429) during createBapiUser. ${details}`); + } + throw error; + } }, getOrCreateUser: async fakeUser => { const existingUser = await self.getUser({ email: fakeUser.email }); @@ -186,13 +201,13 @@ export const createUserService = (clerkClient: ClerkClient) => { createFakeOrganization: async userId => { const name = faker.animal.dog(); const organization = await clerkClient.organizations.createOrganization({ - name: faker.animal.dog(), createdBy: userId, + name: faker.animal.dog(), }); return { + delete: () => clerkClient.organizations.deleteOrganization(organization.id), name, organization, - delete: () => clerkClient.organizations.deleteOrganization(organization.id), } satisfies FakeOrganization; }, createFakeAPIKey: async (userId: string) => { From e8305125e660aaf72fa5271f8ce68aa4ed16f36a Mon Sep 17 00:00:00 2001 From: Jacek Date: Wed, 5 Nov 2025 22:30:11 -0600 Subject: [PATCH 3/4] wip --- integration/testUtils/usersService.ts | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/integration/testUtils/usersService.ts b/integration/testUtils/usersService.ts index ba7b8c17d82..e668f86e72f 100644 --- a/integration/testUtils/usersService.ts +++ b/integration/testUtils/usersService.ts @@ -135,17 +135,23 @@ export const createUserService = (clerkClient: ClerkClient) => { skipPasswordRequirement: fakeUser.password === undefined, username: fakeUser.username, }); - } catch (error: any) { - if (error?.status === 429) { + } catch (error: unknown) { + if (typeof error === 'object' && error !== null && 'status' in error && error.status === 429) { + const clerkError = error as { + status: number; + retryAfter?: number; + clerkTraceId?: string; + errors?: Array<{ message: string }>; + }; const details = [ - `Retry-After: ${error.retryAfter ?? 'not provided'} seconds`, - error.clerkTraceId ? `Trace ID: ${error.clerkTraceId}` : null, - error.errors?.length > 0 ? `API Errors: ${error.errors.map((e: any) => e.message).join(', ')}` : null, + `Retry-After: ${clerkError.retryAfter ?? 'not provided'} seconds`, + clerkError.clerkTraceId ? `Trace ID: ${clerkError.clerkTraceId}` : null, + clerkError.errors?.length > 0 ? `API Errors: ${clerkError.errors.map(e => e.message).join(', ')}` : null, ] .filter(Boolean) .join(' | '); - throw new Error(`Rate limit exceeded (HTTP 429) during createBapiUser. ${details}`); + throw new Error(`Rate limit exceeded (HTTP 429) during createBapiUser. ${details}`, { cause: error }); } throw error; } @@ -202,7 +208,7 @@ export const createUserService = (clerkClient: ClerkClient) => { const name = faker.animal.dog(); const organization = await clerkClient.organizations.createOrganization({ createdBy: userId, - name: faker.animal.dog(), + name, }); return { delete: () => clerkClient.organizations.deleteOrganization(organization.id), From 46997f7c5372f44df7e5a6840502571a1f94d699 Mon Sep 17 00:00:00 2001 From: Jacek Date: Wed, 5 Nov 2025 22:31:02 -0600 Subject: [PATCH 4/4] chore: empty changeset --- .changeset/dirty-friends-kick.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changeset/dirty-friends-kick.md diff --git a/.changeset/dirty-friends-kick.md b/.changeset/dirty-friends-kick.md new file mode 100644 index 00000000000..a845151cc84 --- /dev/null +++ b/.changeset/dirty-friends-kick.md @@ -0,0 +1,2 @@ +--- +---