Skip to content

Commit

Permalink
feat(clerk-js,shared,nextjs,react-router,clerk-react,remix): Introduc…
Browse files Browse the repository at this point in the history
…e `EmailLinkErrorCodeStatus` (#5142)
  • Loading branch information
alexcarpenter authored Feb 13, 2025
1 parent 5cc1c78 commit d76c469
Show file tree
Hide file tree
Showing 13 changed files with 44 additions and 16 deletions.
15 changes: 15 additions & 0 deletions .changeset/dry-keys-look.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
'@clerk/react-router': minor
'@clerk/clerk-js': minor
'@clerk/nextjs': minor
'@clerk/shared': minor
'@clerk/clerk-react': minor
'@clerk/remix': minor
---

Introduce `EmailLinkErrorCodeStatus` to support users in custom flows and mark `EmailLinkErrorCode` as deprecated.

```diff
- import { EmailLinkErrorCode } from '@clerk/nextjs/errors'
+ import { EmailLinkErrorCodeStatus } from '@clerk/nextjs/errors'
```
10 changes: 5 additions & 5 deletions packages/clerk-js/src/core/__tests__/clerk.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type { DevBrowser } from '../auth/devBrowser';
import { Clerk } from '../clerk';
import { eventBus, events } from '../events';
import type { DisplayConfig, Organization } from '../resources/internal';
import { BaseResource, Client, EmailLinkErrorCode, Environment, SignIn, SignUp } from '../resources/internal';
import { BaseResource, Client, EmailLinkErrorCodeStatus, Environment, SignIn, SignUp } from '../resources/internal';
import { mockJwt } from '../test/fixtures';

const mockClientFetch = jest.fn();
Expand Down Expand Up @@ -1878,7 +1878,7 @@ describe('Clerk singleton', () => {

await expect(async () => {
await sut.handleEmailLinkVerification({});
}).rejects.toThrow(EmailLinkErrorCode.Expired);
}).rejects.toThrow(EmailLinkErrorCodeStatus.Expired);
expect(mockSetActive).not.toHaveBeenCalled();
});

Expand All @@ -1900,7 +1900,7 @@ describe('Clerk singleton', () => {

await expect(async () => {
await sut.handleEmailLinkVerification({});
}).rejects.toThrow(EmailLinkErrorCode.Failed);
}).rejects.toThrow(EmailLinkErrorCodeStatus.Failed);
expect(mockSetActive).not.toHaveBeenCalled();
});

Expand Down Expand Up @@ -1946,7 +1946,7 @@ describe('Clerk singleton', () => {
sut.setActive = mockSetActive;
await expect(async () => {
await sut.handleEmailLinkVerification({});
}).rejects.toThrow(EmailLinkErrorCode.Failed);
}).rejects.toThrow(EmailLinkErrorCodeStatus.Failed);
expect(mockSetActive).not.toHaveBeenCalled();
});

Expand All @@ -1972,7 +1972,7 @@ describe('Clerk singleton', () => {

await expect(async () => {
await sut.handleEmailLinkVerification({});
}).rejects.toThrow(EmailLinkErrorCode.Failed);
}).rejects.toThrow(EmailLinkErrorCodeStatus.Failed);
expect(mockSetActive).not.toHaveBeenCalled();
});
});
Expand Down
9 changes: 4 additions & 5 deletions packages/clerk-js/src/core/clerk.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { inBrowser as inClientSide, isValidBrowserOnline } from '@clerk/shared/browser';
import { deprecated } from '@clerk/shared/deprecated';
import { ClerkRuntimeError, is4xxError, isClerkAPIResponseError } from '@clerk/shared/error';
import { ClerkRuntimeError, EmailLinkErrorCodeStatus, is4xxError, isClerkAPIResponseError } from '@clerk/shared/error';
import { parsePublishableKey } from '@clerk/shared/keys';
import { LocalStorageBroadcastChannel } from '@clerk/shared/localStorageBroadcastChannel';
import { logger } from '@clerk/shared/logger';
Expand Down Expand Up @@ -120,7 +120,6 @@ import {
BaseResource,
Client,
EmailLinkError,
EmailLinkErrorCode,
Environment,
isClerkRuntimeError,
Organization,
Expand Down Expand Up @@ -1216,11 +1215,11 @@ export class Clerk implements ClerkInterface {

const verificationStatus = getClerkQueryParam('__clerk_status');
if (verificationStatus === 'expired') {
throw new EmailLinkError(EmailLinkErrorCode.Expired);
throw new EmailLinkError(EmailLinkErrorCodeStatus.Expired);
} else if (verificationStatus === 'client_mismatch') {
throw new EmailLinkError(EmailLinkErrorCode.ClientMismatch);
throw new EmailLinkError(EmailLinkErrorCodeStatus.ClientMismatch);
} else if (verificationStatus !== 'verified') {
throw new EmailLinkError(EmailLinkErrorCode.Failed);
throw new EmailLinkError(EmailLinkErrorCodeStatus.Failed);
}

const newSessionId = getClerkQueryParam('__clerk_created_session');
Expand Down
1 change: 1 addition & 0 deletions packages/clerk-js/src/core/resources/Error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export {
ClerkAPIResponseError,
EmailLinkError,
EmailLinkErrorCode,
EmailLinkErrorCodeStatus,
isClerkAPIResponseError,
isClerkRuntimeError,
isEmailLinkError,
Expand Down
6 changes: 3 additions & 3 deletions packages/clerk-js/src/ui/common/EmailLinkVerify.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { EmailLinkErrorCode, isEmailLinkError } from '@clerk/shared/error';
import { EmailLinkErrorCodeStatus, isEmailLinkError } from '@clerk/shared/error';
import { useClerk } from '@clerk/shared/react';
import React from 'react';

Expand Down Expand Up @@ -42,10 +42,10 @@ export const EmailLinkVerify = (props: EmailLinkVerifyProps) => {
});
} catch (err) {
let status: VerificationStatus = 'failed';
if (isEmailLinkError(err) && err.code === EmailLinkErrorCode.Expired) {
if (isEmailLinkError(err) && err.code === EmailLinkErrorCodeStatus.Expired) {
status = 'expired';
}
if (isEmailLinkError(err) && err.code === EmailLinkErrorCode.ClientMismatch) {
if (isEmailLinkError(err) && err.code === EmailLinkErrorCodeStatus.ClientMismatch) {
status = 'client_mismatch';
}
setVerificationStatus(status);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';

import { EmailLinkError, EmailLinkErrorCode } from '../../../../core/resources';
import { EmailLinkError, EmailLinkErrorCodeStatus } from '../../../../core/resources';
import { render, runFakeTimers, screen, waitFor } from '../../../../testUtils';
import { SignUpEmailLinkFlowComplete } from '../../../common/EmailLinkCompleteFlowCard';
import { bindCreateFixtures } from '../../../utils/test/createFixtures';
Expand Down Expand Up @@ -50,7 +50,7 @@ describe('SignUpEmailLinkFlowComplete', () => {
});
fixtures.clerk.handleEmailLinkVerification.mockImplementationOnce(
await Promise.resolve(() => {
throw new EmailLinkError(EmailLinkErrorCode.Expired);
throw new EmailLinkError(EmailLinkErrorCodeStatus.Expired);
}),
);

Expand All @@ -68,7 +68,7 @@ describe('SignUpEmailLinkFlowComplete', () => {
});
fixtures.clerk.handleEmailLinkVerification.mockImplementationOnce(
await Promise.resolve(() => {
throw new EmailLinkError(EmailLinkErrorCode.Failed);
throw new EmailLinkError(EmailLinkErrorCodeStatus.Failed);
}),
);
await runFakeTimers(async timers => {
Expand Down
1 change: 1 addition & 0 deletions packages/nextjs/src/client-boundary/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export {
isKnownError,
isMetamaskError,
EmailLinkErrorCode,
EmailLinkErrorCodeStatus,
} from '@clerk/clerk-react/errors';

export { usePromisifiedAuth as useAuth } from './PromisifiedAuthProvider';
1 change: 1 addition & 0 deletions packages/nextjs/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export {
isKnownError,
isMetamaskError,
EmailLinkErrorCode,
EmailLinkErrorCodeStatus,
} from './client-boundary/hooks';

export { isClerkAPIResponseError } from '@clerk/clerk-react/errors';
1 change: 1 addition & 0 deletions packages/react-router/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export {
isKnownError,
isMetamaskError,
EmailLinkErrorCode,
EmailLinkErrorCodeStatus,
} from '@clerk/clerk-react/errors';
1 change: 1 addition & 0 deletions packages/react/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export {
isKnownError,
isMetamaskError,
EmailLinkErrorCode,
EmailLinkErrorCodeStatus,
} from '@clerk/shared/error';
1 change: 1 addition & 0 deletions packages/remix/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export {
isKnownError,
isMetamaskError,
EmailLinkErrorCode,
EmailLinkErrorCodeStatus,
} from '@clerk/clerk-react/errors';
7 changes: 7 additions & 0 deletions packages/shared/src/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,19 @@ export function isEmailLinkError(err: Error): err is EmailLinkError {
return err.name === 'EmailLinkError';
}

/** @deprecated Please use `EmailLinkErrorCodeStatus` instead.*/
export const EmailLinkErrorCode = {
Expired: 'expired',
Failed: 'failed',
ClientMismatch: 'client_mismatch',
};

export const EmailLinkErrorCodeStatus = {
Expired: 'expired',
Failed: 'failed',
ClientMismatch: 'client_mismatch',
} as const;

const DefaultMessages = Object.freeze({
InvalidProxyUrlErrorMessage: `The proxyUrl passed to Clerk is invalid. The expected value for proxyUrl is an absolute URL or a relative path with a leading '/'. (key={{url}})`,
InvalidPublishableKeyErrorMessage: `The publishableKey passed to Clerk is invalid. You can get your Publishable key at https://dashboard.clerk.com/last-active?path=api-keys. (key={{key}})`,
Expand Down
1 change: 1 addition & 0 deletions packages/tanstack-start/src/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export {
isKnownError,
isMetamaskError,
EmailLinkErrorCode,
EmailLinkErrorCodeStatus,
} from '@clerk/clerk-react/errors';

0 comments on commit d76c469

Please sign in to comment.