From b28c5e8bc44885bf6b1533df48e872ba90c387da Mon Sep 17 00:00:00 2001 From: panteliselef Date: Fri, 15 Nov 2024 08:52:52 -0500 Subject: [PATCH] chore(shared): Improve formatting of ClerkRuntimeError message (#4574) --- .changeset/nine-kids-matter.md | 5 ++++ packages/shared/src/__tests__/error.test.ts | 32 ++++++++++++++++++++- packages/shared/src/error.ts | 9 ++++-- 3 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 .changeset/nine-kids-matter.md diff --git a/.changeset/nine-kids-matter.md b/.changeset/nine-kids-matter.md new file mode 100644 index 0000000000..20a09541b6 --- /dev/null +++ b/.changeset/nine-kids-matter.md @@ -0,0 +1,5 @@ +--- +'@clerk/shared': patch +--- + +Improve formatting of ClerkRuntimeError message to include error code. diff --git a/packages/shared/src/__tests__/error.test.ts b/packages/shared/src/__tests__/error.test.ts index 6d668c99f2..31fd8b2a53 100644 --- a/packages/shared/src/__tests__/error.test.ts +++ b/packages/shared/src/__tests__/error.test.ts @@ -1,5 +1,5 @@ import type { ErrorThrowerOptions } from '../error'; -import { buildErrorThrower } from '../error'; +import { buildErrorThrower, ClerkRuntimeError, isClerkRuntimeError } from '../error'; describe('ErrorThrower', () => { const errorThrower = buildErrorThrower({ packageName: '@clerk/test-package' }); @@ -32,3 +32,33 @@ describe('ErrorThrower', () => { ).toThrow('@clerk/another-test-package: This is a custom error message for key=whatever and an unknown '); }); }); + +describe('ClerkRuntimeError', () => { + const clerkRuntimeError = new ClerkRuntimeError('test', { code: 'test_code' }); + + it('throws the correct error message', () => { + expect(() => { + throw clerkRuntimeError; + }).toThrow(/^🔒 Clerk:\ntest\n\n\(Code: "test_code"\)/); + }); + + it('throws the correct error message without duplicate prefixes', () => { + expect(() => { + throw new ClerkRuntimeError('🔒 Clerk: test', { code: 'test_code' }); + }).toThrow(/^🔒 Clerk:\ntest\n\n\(Code: "test_code"\)/); + }); + + it('properties are populated correctly', () => { + expect(clerkRuntimeError.name).toEqual('ClerkRuntimeError'); + expect(clerkRuntimeError.code).toEqual('test_code'); + expect(clerkRuntimeError.message).toMatch(/🔒 Clerk:\ntest\n\n\(Code: "test_code"\)/); + expect(clerkRuntimeError.clerkRuntimeError).toBe(true); + expect(clerkRuntimeError.toString()).toMatch( + /^\[ClerkRuntimeError\]\nMessage:🔒 Clerk:\ntest\n\n\(Code: "test_code"\)/, + ); + }); + + it('helper recognises error', () => { + expect(isClerkRuntimeError(clerkRuntimeError)).toEqual(true); + }); +}); diff --git a/packages/shared/src/error.ts b/packages/shared/src/error.ts index 957148dfdb..e427a5e72f 100644 --- a/packages/shared/src/error.ts +++ b/packages/shared/src/error.ts @@ -155,13 +155,18 @@ export class ClerkRuntimeError extends Error { code: string; constructor(message: string, { code }: { code: string }) { - super(message); + const prefix = '🔒 Clerk:'; + const regex = new RegExp(prefix.replace(' ', '\\s*'), 'i'); + const sanitized = message.replace(regex, ''); + const _message = `${prefix}\n${sanitized.trim()}\n\n(Code: "${code}")\n`; + super(_message); Object.setPrototypeOf(this, ClerkRuntimeError.prototype); this.code = code; - this.message = message; + this.message = _message; this.clerkRuntimeError = true; + this.name = 'ClerkRuntimeError'; } /**