From f86bfc776cbee7981ac21c27cbf34a5beabb9a32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Og=C3=B3rek?= Date: Wed, 3 Jun 2020 14:20:30 +0200 Subject: [PATCH] fix: Handle DSN qs and show better error messages --- packages/utils/src/dsn.ts | 17 ++++++++++++++--- packages/utils/test/dsn.test.ts | 18 +++++++++++++++--- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/packages/utils/src/dsn.ts b/packages/utils/src/dsn.ts index 54149036f8a8..5b1ee9c0d243 100644 --- a/packages/utils/src/dsn.ts +++ b/packages/utils/src/dsn.ts @@ -72,6 +72,13 @@ export class Dsn implements DsnComponents { projectId = split.pop() as string; } + if (projectId) { + const projectMatch = projectId.match(/^\d+/); + if (projectMatch) { + projectId = projectMatch[0]; + } + } + this._fromComponents({ host, pass, path, projectId, port, protocol: protocol as DsnProtocol, user }); } @@ -90,16 +97,20 @@ export class Dsn implements DsnComponents { private _validate(): void { ['protocol', 'user', 'host', 'projectId'].forEach(component => { if (!this[component as keyof DsnComponents]) { - throw new SentryError(ERROR_MESSAGE); + throw new SentryError(`${ERROR_MESSAGE}: ${component} missing`); } }); + if (!this.projectId.match(/^\d+$/)) { + throw new SentryError(`${ERROR_MESSAGE}: Invalid projectId ${this.projectId}`); + } + if (this.protocol !== 'http' && this.protocol !== 'https') { - throw new SentryError(ERROR_MESSAGE); + throw new SentryError(`${ERROR_MESSAGE}: Invalid protocol ${this.protocol}`); } if (this.port && isNaN(parseInt(this.port, 10))) { - throw new SentryError(ERROR_MESSAGE); + throw new SentryError(`${ERROR_MESSAGE}: Invalid port ${this.port}`); } } } diff --git a/packages/utils/test/dsn.test.ts b/packages/utils/test/dsn.test.ts index 840e95ebde4b..6db6e4f96868 100644 --- a/packages/utils/test/dsn.test.ts +++ b/packages/utils/test/dsn.test.ts @@ -17,8 +17,8 @@ describe('Dsn', () => { expect(dsn.pass).toBe('xyz'); expect(dsn.host).toBe('sentry.io'); expect(dsn.port).toBe('1234'); - expect(dsn.projectId).toBe('123'); expect(dsn.path).toBe(''); + expect(dsn.projectId).toBe('123'); }); test('applies partial components', () => { @@ -33,8 +33,8 @@ describe('Dsn', () => { expect(dsn.pass).toBe(''); expect(dsn.host).toBe('sentry.io'); expect(dsn.port).toBe(''); - expect(dsn.projectId).toBe('123'); expect(dsn.path).toBe(''); + expect(dsn.projectId).toBe('123'); }); test('throws for missing components', () => { @@ -107,8 +107,8 @@ describe('Dsn', () => { expect(dsn.pass).toBe('xyz'); expect(dsn.host).toBe('sentry.io'); expect(dsn.port).toBe('1234'); - expect(dsn.projectId).toBe('123'); expect(dsn.path).toBe(''); + expect(dsn.projectId).toBe('123'); }); test('parses a valid partial Dsn', () => { @@ -133,6 +133,17 @@ describe('Dsn', () => { expect(dsn.projectId).toBe('321'); }); + test('with a query string', () => { + const dsn = new Dsn('https://abc@sentry.io/321?sample.rate=0.1&other=value'); + expect(dsn.protocol).toBe('https'); + expect(dsn.user).toBe('abc'); + expect(dsn.pass).toBe(''); + expect(dsn.host).toBe('sentry.io'); + expect(dsn.port).toBe(''); + expect(dsn.path).toBe(''); + expect(dsn.projectId).toBe('321'); + }); + test('throws when provided invalid Dsn', () => { expect(() => new Dsn('some@random.dsn')).toThrow(SentryError); }); @@ -147,6 +158,7 @@ describe('Dsn', () => { test('throws for invalid fields', () => { expect(() => new Dsn('httpx://abc@sentry.io/123')).toThrow(SentryError); expect(() => new Dsn('httpx://abc@sentry.io:xxx/123')).toThrow(SentryError); + expect(() => new Dsn('http://abc@sentry.io/abc')).toThrow(SentryError); }); });