From b8654bcfe08079dbf38cde251cacf9aae245dc45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Og=C3=B3rek?= Date: Mon, 14 Oct 2019 15:25:22 +0200 Subject: [PATCH 1/2] ref: The smallest possible interface for our needs - PromiseLike --- packages/browser/src/backend.ts | 4 ++-- packages/browser/src/client.ts | 2 +- .../browser/src/integrations/breadcrumbs.ts | 2 +- packages/browser/src/sdk.ts | 4 ++-- packages/browser/src/transports/base.ts | 4 ++-- packages/browser/src/transports/fetch.ts | 2 +- packages/browser/src/transports/xhr.ts | 2 +- .../test/unit/mocks/simpletransport.ts | 2 +- .../test/unit/transports/fetch.test.ts | 2 +- .../browser/test/unit/transports/xhr.test.ts | 2 +- packages/core/src/basebackend.ts | 10 ++++---- packages/core/src/baseclient.ts | 24 +++++++++---------- packages/core/src/transports/noop.ts | 4 ++-- packages/core/test/mocks/backend.ts | 4 ++-- packages/core/test/mocks/transport.ts | 4 ++-- packages/hub/src/scope.ts | 10 ++++---- packages/hub/test/hub.test.ts | 2 +- packages/hub/test/scope.test.ts | 2 +- packages/node/src/backend.ts | 8 +++---- packages/node/src/client.ts | 2 +- packages/node/src/handlers.ts | 2 +- .../node/src/integrations/linkederrors.ts | 12 +++++----- packages/node/src/parsers.ts | 14 +++++++---- packages/node/src/transports/base.ts | 4 ++-- packages/node/test/parsers.test.ts | 10 ++++---- packages/types/src/client.ts | 4 ++-- packages/types/src/eventprocessor.ts | 4 ++-- packages/types/src/options.ts | 2 +- packages/types/src/transport.ts | 4 ++-- packages/typescript/tslint.json | 4 +++- packages/utils/src/async.ts | 4 ++-- packages/utils/src/promisebuffer.ts | 18 +++++++------- packages/utils/src/syncpromise.ts | 20 ++++++++-------- packages/utils/test/promisebuffer.test.ts | 2 +- packages/utils/test/syncpromise.test.ts | 18 +++++++------- 35 files changed, 112 insertions(+), 106 deletions(-) diff --git a/packages/browser/src/backend.ts b/packages/browser/src/backend.ts index da90aaa28125..a7c5847fa1a8 100644 --- a/packages/browser/src/backend.ts +++ b/packages/browser/src/backend.ts @@ -56,7 +56,7 @@ export class BrowserBackend extends BaseBackend { /** * @inheritDoc */ - public eventFromException(exception: any, hint?: EventHint): Promise { + public eventFromException(exception: any, hint?: EventHint): PromiseLike { const syntheticException = (hint && hint.syntheticException) || undefined; const event = eventFromUnknownInput(exception, syntheticException, { attachStacktrace: this._options.attachStacktrace, @@ -74,7 +74,7 @@ export class BrowserBackend extends BaseBackend { /** * @inheritDoc */ - public eventFromMessage(message: string, level: Severity = Severity.Info, hint?: EventHint): Promise { + public eventFromMessage(message: string, level: Severity = Severity.Info, hint?: EventHint): PromiseLike { const syntheticException = (hint && hint.syntheticException) || undefined; const event = eventFromString(message, syntheticException, { attachStacktrace: this._options.attachStacktrace, diff --git a/packages/browser/src/client.ts b/packages/browser/src/client.ts index d0026f8a90c4..7a170c49c68b 100644 --- a/packages/browser/src/client.ts +++ b/packages/browser/src/client.ts @@ -51,7 +51,7 @@ export class BrowserClient extends BaseClient { /** * @inheritDoc */ - protected _prepareEvent(event: Event, scope?: Scope, hint?: EventHint): Promise { + protected _prepareEvent(event: Event, scope?: Scope, hint?: EventHint): PromiseLike { event.platform = event.platform || 'javascript'; event.sdk = { ...event.sdk, diff --git a/packages/browser/src/integrations/breadcrumbs.ts b/packages/browser/src/integrations/breadcrumbs.ts index ea9326fb0de9..76cad9c63c83 100644 --- a/packages/browser/src/integrations/breadcrumbs.ts +++ b/packages/browser/src/integrations/breadcrumbs.ts @@ -276,7 +276,7 @@ export class Breadcrumbs implements Integration { ); return response; }) - .catch((error: Error) => { + .then(null, (error: Error) => { Breadcrumbs.addBreadcrumb( { category: 'fetch', diff --git a/packages/browser/src/sdk.ts b/packages/browser/src/sdk.ts index 9829ed93337d..84555bb43a90 100644 --- a/packages/browser/src/sdk.ts +++ b/packages/browser/src/sdk.ts @@ -133,7 +133,7 @@ export function onLoad(callback: () => void): void { * * @param timeout Maximum time in ms the client should wait. */ -export function flush(timeout?: number): Promise { +export function flush(timeout?: number): PromiseLike { const client = getCurrentHub().getClient(); if (client) { return client.flush(timeout); @@ -147,7 +147,7 @@ export function flush(timeout?: number): Promise { * * @param timeout Maximum time in ms the client should wait. */ -export function close(timeout?: number): Promise { +export function close(timeout?: number): PromiseLike { const client = getCurrentHub().getClient(); if (client) { return client.close(timeout); diff --git a/packages/browser/src/transports/base.ts b/packages/browser/src/transports/base.ts index 3955b3dd8fcc..3829eb0dd925 100644 --- a/packages/browser/src/transports/base.ts +++ b/packages/browser/src/transports/base.ts @@ -19,14 +19,14 @@ export abstract class BaseTransport implements Transport { /** * @inheritDoc */ - public sendEvent(_: Event): Promise { + public sendEvent(_: Event): PromiseLike { throw new SentryError('Transport Class has to implement `sendEvent` method'); } /** * @inheritDoc */ - public close(timeout?: number): Promise { + public close(timeout?: number): PromiseLike { return this._buffer.drain(timeout); } } diff --git a/packages/browser/src/transports/fetch.ts b/packages/browser/src/transports/fetch.ts index bfeca66b7ea3..87d161b20cfe 100644 --- a/packages/browser/src/transports/fetch.ts +++ b/packages/browser/src/transports/fetch.ts @@ -10,7 +10,7 @@ export class FetchTransport extends BaseTransport { /** * @inheritDoc */ - public sendEvent(event: Event): Promise { + public sendEvent(event: Event): PromiseLike { const defaultOptions: RequestInit = { body: JSON.stringify(event), method: 'POST', diff --git a/packages/browser/src/transports/xhr.ts b/packages/browser/src/transports/xhr.ts index 40fa38c21c96..8fa545ad6a36 100644 --- a/packages/browser/src/transports/xhr.ts +++ b/packages/browser/src/transports/xhr.ts @@ -8,7 +8,7 @@ export class XHRTransport extends BaseTransport { /** * @inheritDoc */ - public sendEvent(event: Event): Promise { + public sendEvent(event: Event): PromiseLike { return this._buffer.add( new SyncPromise((resolve, reject) => { const request = new XMLHttpRequest(); diff --git a/packages/browser/test/unit/mocks/simpletransport.ts b/packages/browser/test/unit/mocks/simpletransport.ts index b562d2d7e74e..2f3cf591ba4e 100644 --- a/packages/browser/test/unit/mocks/simpletransport.ts +++ b/packages/browser/test/unit/mocks/simpletransport.ts @@ -4,7 +4,7 @@ import { Event, Response, Status } from '../../../src'; import { BaseTransport } from '../../../src/transports'; export class SimpleTransport extends BaseTransport { - public sendEvent(_: Event): Promise { + public sendEvent(_: Event): PromiseLike { return this._buffer.add( SyncPromise.resolve({ status: Status.fromHttpCode(200), diff --git a/packages/browser/test/unit/transports/fetch.test.ts b/packages/browser/test/unit/transports/fetch.test.ts index 253e2dfb9cd2..02012edb2997 100644 --- a/packages/browser/test/unit/transports/fetch.test.ts +++ b/packages/browser/test/unit/transports/fetch.test.ts @@ -55,7 +55,7 @@ describe('FetchTransport', () => { fetch.returns(Promise.reject(response)); - return transport.sendEvent(payload).catch(res => { + return transport.sendEvent(payload).then(null, res => { expect(res.status).equal(403); expect(fetch.calledOnce).equal(true); expect( diff --git a/packages/browser/test/unit/transports/xhr.test.ts b/packages/browser/test/unit/transports/xhr.test.ts index d35554d55fae..a136c1a0fdd0 100644 --- a/packages/browser/test/unit/transports/xhr.test.ts +++ b/packages/browser/test/unit/transports/xhr.test.ts @@ -47,7 +47,7 @@ describe('XHRTransport', () => { it('rejects with non-200 status code', done => { server.respondWith('POST', transportUrl, [403, {}, '']); - transport.sendEvent(payload).catch(res => { + transport.sendEvent(payload).then(null, res => { expect(res.status).equal(403); const request = server.requests[0]; diff --git a/packages/core/src/basebackend.ts b/packages/core/src/basebackend.ts index b31b895d837a..ddbb7d039581 100644 --- a/packages/core/src/basebackend.ts +++ b/packages/core/src/basebackend.ts @@ -25,10 +25,10 @@ import { NoopTransport } from './transports/noop'; */ export interface Backend { /** Creates a {@link Event} from an exception. */ - eventFromException(exception: any, hint?: EventHint): Promise; + eventFromException(exception: any, hint?: EventHint): PromiseLike; /** Creates a {@link Event} from a plain message. */ - eventFromMessage(message: string, level?: Severity, hint?: EventHint): Promise; + eventFromMessage(message: string, level?: Severity, hint?: EventHint): PromiseLike; /** Submits the event to Sentry */ sendEvent(event: Event): void; @@ -78,14 +78,14 @@ export abstract class BaseBackend implements Backend { /** * @inheritDoc */ - public eventFromException(_exception: any, _hint?: EventHint): Promise { + public eventFromException(_exception: any, _hint?: EventHint): PromiseLike { throw new SentryError('Backend has to implement `eventFromException` method'); } /** * @inheritDoc */ - public eventFromMessage(_message: string, _level?: Severity, _hint?: EventHint): Promise { + public eventFromMessage(_message: string, _level?: Severity, _hint?: EventHint): PromiseLike { throw new SentryError('Backend has to implement `eventFromMessage` method'); } @@ -93,7 +93,7 @@ export abstract class BaseBackend implements Backend { * @inheritDoc */ public sendEvent(event: Event): void { - this._transport.sendEvent(event).catch(reason => { + this._transport.sendEvent(event).then(null, reason => { logger.error(`Error while sending event: ${reason}`); }); } diff --git a/packages/core/src/baseclient.ts b/packages/core/src/baseclient.ts index 3d3031dc1be1..ece83db9563c 100644 --- a/packages/core/src/baseclient.ts +++ b/packages/core/src/baseclient.ts @@ -92,7 +92,7 @@ export abstract class BaseClient implement eventId = finalEvent && finalEvent.event_id; this._processing = false; }) - .catch(reason => { + .then(null, reason => { logger.error(reason); this._processing = false; }); @@ -119,7 +119,7 @@ export abstract class BaseClient implement eventId = finalEvent && finalEvent.event_id; this._processing = false; }) - .catch(reason => { + .then(null, reason => { logger.error(reason); this._processing = false; }); @@ -140,7 +140,7 @@ export abstract class BaseClient implement eventId = finalEvent && finalEvent.event_id; this._processing = false; }) - .catch(reason => { + .then(null, reason => { logger.error(reason); this._processing = false; }); @@ -164,7 +164,7 @@ export abstract class BaseClient implement /** * @inheritDoc */ - public flush(timeout?: number): Promise { + public flush(timeout?: number): PromiseLike { return this._isClientProcessing(timeout).then(status => { clearInterval(status.interval); return this._getBackend() @@ -177,7 +177,7 @@ export abstract class BaseClient implement /** * @inheritDoc */ - public close(timeout?: number): Promise { + public close(timeout?: number): PromiseLike { return this.flush(timeout).then(result => { this.getOptions().enabled = false; return result; @@ -204,7 +204,7 @@ export abstract class BaseClient implement } /** Waits for the client to be done with processing. */ - protected _isClientProcessing(timeout?: number): Promise<{ ready: boolean; interval: number }> { + protected _isClientProcessing(timeout?: number): PromiseLike<{ ready: boolean; interval: number }> { return new SyncPromise<{ ready: boolean; interval: number }>(resolve => { let ticked: number = 0; const tick: number = 1; @@ -255,7 +255,7 @@ export abstract class BaseClient implement * @param scope A scope containing event metadata. * @returns A new event with more information. */ - protected _prepareEvent(event: Event, scope?: Scope, hint?: EventHint): Promise { + protected _prepareEvent(event: Event, scope?: Scope, hint?: EventHint): PromiseLike { const { environment, release, dist, maxValueLength = 250 } = this.getOptions(); const prepared: Event = { ...event }; @@ -327,7 +327,7 @@ export abstract class BaseClient implement * @param scope A scope containing event metadata. * @returns A SyncPromise that resolves with the event or rejects in case event was/will not be send. */ - protected _processEvent(event: Event, hint?: EventHint, scope?: Scope): Promise { + protected _processEvent(event: Event, hint?: EventHint, scope?: Scope): PromiseLike { const { beforeSend, sampleRate } = this.getOptions(); if (!this._isEnabled()) { @@ -362,7 +362,7 @@ export abstract class BaseClient implement if ((typeof beforeSendResult as any) === 'undefined') { logger.error('`beforeSend` method has to return `null` or a valid event.'); } else if (isThenable(beforeSendResult)) { - this._handleAsyncBeforeSend(beforeSendResult as Promise, resolve, reject); + this._handleAsyncBeforeSend(beforeSendResult as PromiseLike, resolve, reject); } else { finalEvent = beforeSendResult as Event | null; @@ -386,7 +386,7 @@ export abstract class BaseClient implement reject('`beforeSend` threw an error, will not send event.'); } }) - .catch(() => { + .then(null, () => { reject('`beforeSend` threw an error, will not send event.'); }); }); @@ -396,7 +396,7 @@ export abstract class BaseClient implement * Resolves before send Promise and calls resolve/reject on parent SyncPromise. */ private _handleAsyncBeforeSend( - beforeSend: Promise, + beforeSend: PromiseLike, resolve: (event: Event) => void, reject: (reason: string) => void, ): void { @@ -410,7 +410,7 @@ export abstract class BaseClient implement this._getBackend().sendEvent(processedEvent); resolve(processedEvent); }) - .catch(e => { + .then(null, e => { reject(`beforeSend rejected with ${e}`); }); } diff --git a/packages/core/src/transports/noop.ts b/packages/core/src/transports/noop.ts index 87405c3cda19..ae026892271e 100644 --- a/packages/core/src/transports/noop.ts +++ b/packages/core/src/transports/noop.ts @@ -6,7 +6,7 @@ export class NoopTransport implements Transport { /** * @inheritDoc */ - public sendEvent(_: Event): Promise { + public sendEvent(_: Event): PromiseLike { return SyncPromise.resolve({ reason: `NoopTransport: Event has been skipped because no Dsn is configured.`, status: Status.Skipped, @@ -16,7 +16,7 @@ export class NoopTransport implements Transport { /** * @inheritDoc */ - public close(_?: number): Promise { + public close(_?: number): PromiseLike { return SyncPromise.resolve(true); } } diff --git a/packages/core/test/mocks/backend.ts b/packages/core/test/mocks/backend.ts index 4c6c144fa5c5..dfd9efa5da12 100644 --- a/packages/core/test/mocks/backend.ts +++ b/packages/core/test/mocks/backend.ts @@ -37,7 +37,7 @@ export class TestBackend extends BaseBackend { return super._setupTransport(); } - public eventFromException(exception: any): Promise { + public eventFromException(exception: any): PromiseLike { return SyncPromise.resolve({ exception: { values: [ @@ -50,7 +50,7 @@ export class TestBackend extends BaseBackend { }); } - public eventFromMessage(message: string): Promise { + public eventFromMessage(message: string): PromiseLike { return SyncPromise.resolve({ message }); } diff --git a/packages/core/test/mocks/transport.ts b/packages/core/test/mocks/transport.ts index 4c222fa1aeb0..fecebec88fd2 100644 --- a/packages/core/test/mocks/transport.ts +++ b/packages/core/test/mocks/transport.ts @@ -13,7 +13,7 @@ export class FakeTransport implements Transport { public sentCount: number = 0; public delay: number = 2000; - public sendEvent(_event: Event): Promise { + public sendEvent(_event: Event): PromiseLike { this.sendCalled += 1; return this._buffer.add( new SyncPromise(async res => { @@ -24,7 +24,7 @@ export class FakeTransport implements Transport { ); } - public close(timeout?: number): Promise { + public close(timeout?: number): PromiseLike { return this._buffer.drain(timeout); } } diff --git a/packages/hub/src/scope.ts b/packages/hub/src/scope.ts index 8fd3b2fc929e..968315aece41 100644 --- a/packages/hub/src/scope.ts +++ b/packages/hub/src/scope.ts @@ -83,7 +83,7 @@ export class Scope implements ScopeInterface { event: Event | null, hint?: EventHint, index: number = 0, - ): Promise { + ): PromiseLike { return new SyncPromise((resolve, reject) => { const processor = processors[index]; // tslint:disable-next-line:strict-type-predicates @@ -92,13 +92,13 @@ export class Scope implements ScopeInterface { } else { const result = processor({ ...event }, hint) as Event | null; if (isThenable(result)) { - (result as Promise) + (result as PromiseLike) .then(final => this._notifyEventProcessors(processors, final, hint, index + 1).then(resolve)) - .catch(reject); + .then(null, reject); } else { this._notifyEventProcessors(processors, result, hint, index + 1) .then(resolve) - .catch(reject); + .then(null, reject); } } }); @@ -311,7 +311,7 @@ export class Scope implements ScopeInterface { * @param hint May contain additional informartion about the original exception. * @hidden */ - public applyToEvent(event: Event, hint?: EventHint): Promise { + public applyToEvent(event: Event, hint?: EventHint): PromiseLike { if (this._extra && Object.keys(this._extra).length) { event.extra = { ...this._extra, ...event.extra }; } diff --git a/packages/hub/test/hub.test.ts b/packages/hub/test/hub.test.ts index f7c217d4e78a..5bb1945991ab 100644 --- a/packages/hub/test/hub.test.ts +++ b/packages/hub/test/hub.test.ts @@ -263,7 +263,7 @@ describe('Hub', () => { expect(appliedEvent!.breadcrumbs![1].message).toEqual('scope breadcrumb'); expect(appliedEvent!.breadcrumbs![1]).toHaveProperty('timestamp'); }) - .catch(e => { + .then(null, e => { console.error(e); }); }); diff --git a/packages/hub/test/scope.test.ts b/packages/hub/test/scope.test.ts index 59c378efb022..25ac147d6419 100644 --- a/packages/hub/test/scope.test.ts +++ b/packages/hub/test/scope.test.ts @@ -374,7 +374,7 @@ describe('Scope', () => { return processedEvent; }); - return localScope.applyToEvent(event).catch(reason => { + return localScope.applyToEvent(event).then(null, reason => { expect(reason).toEqual('bla'); }); }); diff --git a/packages/node/src/backend.ts b/packages/node/src/backend.ts index 93f7ac2d56a2..8b1d6c53241f 100644 --- a/packages/node/src/backend.ts +++ b/packages/node/src/backend.ts @@ -76,7 +76,7 @@ export class NodeBackend extends BaseBackend { /** * @inheritDoc */ - public eventFromException(exception: any, hint?: EventHint): Promise { + public eventFromException(exception: any, hint?: EventHint): PromiseLike { let ex: any = exception; const mechanism: Mechanism = { handled: true, @@ -114,14 +114,14 @@ export class NodeBackend extends BaseBackend { event_id: hint && hint.event_id, }); }) - .catch(reject), + .then(null, reject), ); } /** * @inheritDoc */ - public eventFromMessage(message: string, level: Severity = Severity.Info, hint?: EventHint): Promise { + public eventFromMessage(message: string, level: Severity = Severity.Info, hint?: EventHint): PromiseLike { const event: Event = { event_id: hint && hint.event_id, level, @@ -138,7 +138,7 @@ export class NodeBackend extends BaseBackend { }; resolve(event); }) - .catch(() => { + .then(null, () => { resolve(event); }); } else { diff --git a/packages/node/src/client.ts b/packages/node/src/client.ts index 83622a423d0a..bf4230416f0e 100644 --- a/packages/node/src/client.ts +++ b/packages/node/src/client.ts @@ -22,7 +22,7 @@ export class NodeClient extends BaseClient { /** * @inheritDoc */ - protected _prepareEvent(event: Event, scope?: Scope, hint?: EventHint): Promise { + protected _prepareEvent(event: Event, scope?: Scope, hint?: EventHint): PromiseLike { event.platform = event.platform || 'node'; event.sdk = { ...event.sdk, diff --git a/packages/node/src/handlers.ts b/packages/node/src/handlers.ts index 97186459c3ee..b9a72da7b394 100644 --- a/packages/node/src/handlers.ts +++ b/packages/node/src/handlers.ts @@ -263,7 +263,7 @@ export function requestHandler(options?: { .then(() => { _end.call(this, chunk, encoding, cb); }) - .catch(e => { + .then(null, e => { logger.error(e); }); }; diff --git a/packages/node/src/integrations/linkederrors.ts b/packages/node/src/integrations/linkederrors.ts index 080885661200..3c917bef5f21 100644 --- a/packages/node/src/integrations/linkederrors.ts +++ b/packages/node/src/integrations/linkederrors.ts @@ -43,7 +43,7 @@ export class LinkedErrors implements Integration { addGlobalEventProcessor((event: Event, hint?: EventHint) => { const self = getCurrentHub().getIntegration(LinkedErrors); if (self) { - return (self.handler(event, hint) as unknown) as Promise; + return (self.handler(event, hint) as unknown) as PromiseLike; } return event; }); @@ -52,7 +52,7 @@ export class LinkedErrors implements Integration { /** * @inheritDoc */ - public handler(event: Event, hint?: EventHint): Promise { + public handler(event: Event, hint?: EventHint): PromiseLike { if (!event.exception || !event.exception.values || !hint || !(hint.originalException instanceof Error)) { return SyncPromise.resolve(event); } @@ -65,7 +65,7 @@ export class LinkedErrors implements Integration { } resolve(event); }) - .catch(() => { + .then(null, () => { resolve(event); }); }); @@ -74,7 +74,7 @@ export class LinkedErrors implements Integration { /** * @inheritDoc */ - public walkErrorTree(error: ExtendedError, key: string, stack: Exception[] = []): Promise { + public walkErrorTree(error: ExtendedError, key: string, stack: Exception[] = []): PromiseLike { if (!(error[key] instanceof Error) || stack.length + 1 >= this._limit) { return SyncPromise.resolve(stack); } @@ -83,11 +83,11 @@ export class LinkedErrors implements Integration { .then((exception: Exception) => { this.walkErrorTree(error[key], key, [exception, ...stack]) .then(resolve) - .catch(() => { + .then(null, () => { reject(); }); }) - .catch(() => { + .then(null, () => { reject(); }); }); diff --git a/packages/node/src/parsers.ts b/packages/node/src/parsers.ts index bc7713686c5d..e78a04c82ab3 100644 --- a/packages/node/src/parsers.ts +++ b/packages/node/src/parsers.ts @@ -67,7 +67,7 @@ function getModule(filename: string, base?: string): string { * * @param filenames Array of filepaths to read content from. */ -function readSourceFiles(filenames: string[]): Promise<{ [key: string]: string | null }> { +function readSourceFiles(filenames: string[]): PromiseLike<{ [key: string]: string | null }> { // we're relying on filenames being de-duped already if (filenames.length === 0) { return SyncPromise.resolve({}); @@ -132,7 +132,7 @@ export function extractStackFromError(error: Error): stacktrace.StackFrame[] { /** * @hidden */ -export function parseStack(stack: stacktrace.StackFrame[], options?: NodeOptions): Promise { +export function parseStack(stack: stacktrace.StackFrame[], options?: NodeOptions): PromiseLike { const filesToRead: string[] = []; const linesOfContext = @@ -191,7 +191,11 @@ export function parseStack(stack: stacktrace.StackFrame[], options?: NodeOptions * @param filesToRead string[] of filepaths * @param frames StackFrame[] containg all frames */ -function addPrePostContext(filesToRead: string[], frames: StackFrame[], linesOfContext: number): Promise { +function addPrePostContext( + filesToRead: string[], + frames: StackFrame[], + linesOfContext: number, +): PromiseLike { return new SyncPromise(resolve => readSourceFiles(filesToRead).then(sourceFiles => { const result = frames.map(frame => { @@ -224,7 +228,7 @@ function addPrePostContext(filesToRead: string[], frames: StackFrame[], linesOfC /** * @hidden */ -export function getExceptionFromError(error: Error, options?: NodeOptions): Promise { +export function getExceptionFromError(error: Error, options?: NodeOptions): PromiseLike { const name = error.name || error.constructor.name; const stack = extractStackFromError(error); return new SyncPromise(resolve => @@ -244,7 +248,7 @@ export function getExceptionFromError(error: Error, options?: NodeOptions): Prom /** * @hidden */ -export function parseError(error: ExtendedError, options?: NodeOptions): Promise { +export function parseError(error: ExtendedError, options?: NodeOptions): PromiseLike { return new SyncPromise(resolve => getExceptionFromError(error, options).then((exception: Exception) => { resolve({ diff --git a/packages/node/src/transports/base.ts b/packages/node/src/transports/base.ts index d0599eab6d78..29b4f81d6ccd 100644 --- a/packages/node/src/transports/base.ts +++ b/packages/node/src/transports/base.ts @@ -108,14 +108,14 @@ export abstract class BaseTransport implements Transport { /** * @inheritDoc */ - public sendEvent(_: Event): Promise { + public sendEvent(_: Event): PromiseLike { throw new SentryError('Transport Class has to implement `sendEvent` method.'); } /** * @inheritDoc */ - public close(timeout?: number): Promise { + public close(timeout?: number): PromiseLike { return this._buffer.drain(timeout); } } diff --git a/packages/node/test/parsers.test.ts b/packages/node/test/parsers.test.ts index ae1e334c2a11..f89e15a2e54d 100644 --- a/packages/node/test/parsers.test.ts +++ b/packages/node/test/parsers.test.ts @@ -32,11 +32,11 @@ describe('parsers.ts', () => { expect(spy).toHaveBeenCalledTimes(mockCalls); done(); }) - .catch(() => { + .then(null, () => { // no-empty }); }) - .catch(() => { + .then(null, () => { // no-empty }); }); @@ -57,15 +57,15 @@ describe('parsers.ts', () => { expect(spy).toHaveBeenCalledTimes(newErrorCalls); done(); }) - .catch(() => { + .then(null, () => { // no-empty }); }) - .catch(() => { + .then(null, () => { // no-empty }); }) - .catch(() => { + .then(null, () => { // no-empty }); }); diff --git a/packages/types/src/client.ts b/packages/types/src/client.ts index c01f091c4e89..90985723f6e6 100644 --- a/packages/types/src/client.ts +++ b/packages/types/src/client.ts @@ -58,7 +58,7 @@ export interface Client { * * @param timeout Maximum time in ms the client should wait. */ - close(timeout?: number): Promise; + close(timeout?: number): PromiseLike; /** * A promise that resolves when all current events have been sent. @@ -66,7 +66,7 @@ export interface Client { * * @param timeout Maximum time in ms the client should wait. */ - flush(timeout?: number): Promise; + flush(timeout?: number): PromiseLike; /** Returns an array of installed integrations on the client. */ getIntegration(integartion: IntegrationClass): T | null; diff --git a/packages/types/src/eventprocessor.ts b/packages/types/src/eventprocessor.ts index 07789fc40d76..13727ae2e797 100644 --- a/packages/types/src/eventprocessor.ts +++ b/packages/types/src/eventprocessor.ts @@ -3,7 +3,7 @@ import { Event, EventHint } from './event'; /** * Event processors are used to change the event before it will be send. * We strongly advise to make this function sync. - * Returning a Promise will work just fine, but better be sure that you know what you are doing. + * Returning a PromiseLike will work just fine, but better be sure that you know what you are doing. * Event processing will be deferred until your Promise is resolved. */ -export type EventProcessor = (event: Event, hint?: EventHint) => Promise | Event | null; +export type EventProcessor = (event: Event, hint?: EventHint) => PromiseLike | Event | null; diff --git a/packages/types/src/options.ts b/packages/types/src/options.ts index 3eaed29b149b..ac31e40f41cc 100644 --- a/packages/types/src/options.ts +++ b/packages/types/src/options.ts @@ -96,7 +96,7 @@ export interface Options { * @param hint May contain additional information about the original exception. * @returns A new event that will be sent | null. */ - beforeSend?(event: Event, hint?: EventHint): Promise | Event | null; + beforeSend?(event: Event, hint?: EventHint): PromiseLike | Event | null; /** * A callback invoked when adding a breadcrumb, allowing to optionally modify diff --git a/packages/types/src/transport.ts b/packages/types/src/transport.ts index 42227a5d570c..23d874a871ee 100644 --- a/packages/types/src/transport.ts +++ b/packages/types/src/transport.ts @@ -9,14 +9,14 @@ export interface Transport { * * @param body String body that should be sent to Sentry. */ - sendEvent(event: Event): Promise; + sendEvent(event: Event): PromiseLike; /** * Call this function to wait until all pending requests have been sent. * * @param timeout Number time in ms to wait until the buffer is drained. */ - close(timeout?: number): Promise; + close(timeout?: number): PromiseLike; } /** JSDoc */ diff --git a/packages/typescript/tslint.json b/packages/typescript/tslint.json index b6e7db3053f1..cff8840729ba 100644 --- a/packages/typescript/tslint.json +++ b/packages/typescript/tslint.json @@ -80,6 +80,8 @@ // this config will apply to properties AND methods, if you only need it for properties, use "property" instead of "member" { "type": "member", "modifiers": "protected", "leadingUnderscore": "require" }, { "type": "member", "modifiers": "private", "leadingUnderscore": "require" } - ] + ], + // we cannot use Promises as they are not IE10-11 compatibile, so we had to create our own implementation + "await-promise": [true, "PromiseLike"] } } diff --git a/packages/utils/src/async.ts b/packages/utils/src/async.ts index 7ed174d0be15..736a048be60b 100644 --- a/packages/utils/src/async.ts +++ b/packages/utils/src/async.ts @@ -2,8 +2,8 @@ * Consumes the promise and logs the error when it rejects. * @param promise A promise to forget. */ -export function forget(promise: Promise): void { - promise.catch(e => { +export function forget(promise: PromiseLike): void { + promise.then(null, e => { // TODO: Use a better logging mechanism console.error(e); }); diff --git a/packages/utils/src/promisebuffer.ts b/packages/utils/src/promisebuffer.ts index 018180aec108..4bb0d4c9ca9e 100644 --- a/packages/utils/src/promisebuffer.ts +++ b/packages/utils/src/promisebuffer.ts @@ -6,7 +6,7 @@ export class PromiseBuffer { public constructor(protected _limit?: number) {} /** Internal set of queued Promises */ - private readonly _buffer: Array> = []; + private readonly _buffer: Array> = []; /** * Says if the buffer is ready to take more requests @@ -18,10 +18,10 @@ export class PromiseBuffer { /** * Add a promise to the queue. * - * @param task Can be any Promise + * @param task Can be any PromiseLike * @returns The original promise. */ - public add(task: Promise): Promise { + public add(task: PromiseLike): PromiseLike { if (!this.isReady()) { return SyncPromise.reject(new SentryError('Not adding Promise due to buffer limit reached.')); } @@ -30,8 +30,8 @@ export class PromiseBuffer { } task .then(() => this.remove(task)) - .catch(() => - this.remove(task).catch(() => { + .then(null, () => + this.remove(task).then(null, () => { // We have to add this catch here otherwise we have an unhandledPromiseRejection // because it's a new Promise chain. }), @@ -42,10 +42,10 @@ export class PromiseBuffer { /** * Remove a promise to the queue. * - * @param task Can be any Promise + * @param task Can be any PromiseLike * @returns Removed promise. */ - public remove(task: Promise): Promise { + public remove(task: PromiseLike): PromiseLike { const removedTask = this._buffer.splice(this._buffer.indexOf(task), 1)[0]; return removedTask; } @@ -63,7 +63,7 @@ export class PromiseBuffer { * * @param timeout Number in ms to wait until it resolves with false. */ - public drain(timeout?: number): Promise { + public drain(timeout?: number): PromiseLike { return new SyncPromise(resolve => { const capturedSetTimeout = setTimeout(() => { if (timeout && timeout > 0) { @@ -75,7 +75,7 @@ export class PromiseBuffer { clearTimeout(capturedSetTimeout); resolve(true); }) - .catch(() => { + .then(null, () => { resolve(true); }); }); diff --git a/packages/utils/src/syncpromise.ts b/packages/utils/src/syncpromise.ts index 99c425dbbf54..6a9f5e58944d 100644 --- a/packages/utils/src/syncpromise.ts +++ b/packages/utils/src/syncpromise.ts @@ -14,7 +14,7 @@ enum States { * Thenable class that behaves like a Promise and follows it's interface * but is not async internally */ -export class SyncPromise implements Promise { +class SyncPromise implements PromiseLike { private _state: States = States.PENDING; private _handlers: Array<{ onfulfilled?: ((value: T) => T | PromiseLike) | null; @@ -37,24 +37,22 @@ export class SyncPromise implements Promise { return '[object SyncPromise]'; } - public [Symbol.toStringTag]: string = '[object SyncPromise]'; - /** JSDoc */ - public static resolve(value: T | PromiseLike): Promise { + public static resolve(value: T | PromiseLike): PromiseLike { return new SyncPromise(resolve => { resolve(value); }); } /** JSDoc */ - public static reject(reason?: any): Promise { + public static reject(reason?: any): PromiseLike { return new SyncPromise((_, reject) => { reject(reason); }); } /** JSDoc */ - public static all(collection: Array>): Promise { + public static all(collection: Array>): PromiseLike { return new SyncPromise((resolve, reject) => { if (!Array.isArray(collection)) { reject(new TypeError(`Promise.all requires an array as input.`)); @@ -80,7 +78,7 @@ export class SyncPromise implements Promise { } resolve(resolvedCollection); }) - .catch(reject); + .then(null, reject); }); }); } @@ -89,7 +87,7 @@ export class SyncPromise implements Promise { public then( onfulfilled?: ((value: T) => TResult1 | PromiseLike) | null, onrejected?: ((reason: any) => TResult2 | PromiseLike) | null, - ): Promise { + ): PromiseLike { return new SyncPromise((resolve, reject) => { this._attachHandler({ onfulfilled: result => { @@ -127,12 +125,12 @@ export class SyncPromise implements Promise { /** JSDoc */ public catch( onrejected?: ((reason: any) => TResult | PromiseLike) | null, - ): Promise { + ): PromiseLike { return this.then(val => val, onrejected); } /** JSDoc */ - public finally(onfinally?: (() => void) | null): Promise { + public finally(onfinally?: (() => void) | null): PromiseLike { return new SyncPromise((resolve, reject) => { let val: TResult | any; let isRejected: boolean; @@ -227,3 +225,5 @@ export class SyncPromise implements Promise { this._handlers = []; }; } + +export { SyncPromise }; diff --git a/packages/utils/test/promisebuffer.test.ts b/packages/utils/test/promisebuffer.test.ts index 6dff403b02bd..26379e4fbc5b 100644 --- a/packages/utils/test/promisebuffer.test.ts +++ b/packages/utils/test/promisebuffer.test.ts @@ -98,7 +98,7 @@ describe('PromiseBuffer', () => { const q = new PromiseBuffer(); const p = new Promise((_, reject) => setTimeout(reject, 1)); jest.runAllTimers(); - return q.add(p).catch(() => { + return q.add(p).then(null, () => { expect(true).toBe(true); }); }); diff --git a/packages/utils/test/syncpromise.test.ts b/packages/utils/test/syncpromise.test.ts index 16a86c7201b8..685edabd6861 100644 --- a/packages/utils/test/syncpromise.test.ts +++ b/packages/utils/test/syncpromise.test.ts @@ -40,11 +40,11 @@ describe('SyncPromise', () => { resolve('3'); }); - const fp = async (s: Promise, prepend: string) => + const fp = async (s: PromiseLike, prepend: string) => new Promise(resolve => { s.then(val => { resolve(prepend + val); - }).catch(_ => { + }).then(null, _ => { // bla }); }); @@ -72,7 +72,7 @@ describe('SyncPromise', () => { new SyncPromise(resolve => { s.then(val => { resolve(prepend + val); - }).catch(() => { + }).then(null, () => { // no-empty }); }); @@ -104,7 +104,7 @@ describe('SyncPromise', () => { resolve(41); }) .then(done) - .catch(_ => { + .then(null, _ => { // }); }).then(val => { @@ -149,13 +149,13 @@ describe('SyncPromise', () => { ); qp.then(value => { expect(value).toEqual(2); - }).catch(() => { + }).then(null, () => { // no-empty }); expect(qp).not.toHaveProperty('_value'); qp.then(value => { expect(value).toEqual(2); - }).catch(() => { + }).then(null, () => { // no-empty }); jest.runAllTimers(); @@ -224,7 +224,7 @@ describe('SyncPromise', () => { .then(_ => { expect(true).toBeFalsy(); }) - .catch(reason => { + .then(null, reason => { expect(reason).toBe('test'); }); }); @@ -234,7 +234,7 @@ describe('SyncPromise', () => { return new SyncPromise((_, reject) => { reject('test'); - }).catch(reason => { + }).then(null, reason => { expect(reason).toBe('test'); }); }); @@ -249,7 +249,7 @@ describe('SyncPromise', () => { expect(value).toEqual(2); return SyncPromise.reject('wat'); }) - .catch(reason => { + .then(null, reason => { expect(reason).toBe('wat'); }); }); From 928b45564cd4fb6be5df49b7a67ea4ab0b39bfaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Og=C3=B3rek?= Date: Mon, 14 Oct 2019 15:25:57 +0200 Subject: [PATCH 2/2] ref: Remove rollup-modify-plugin as we dont use it anymore --- packages/browser/package.json | 1 - packages/browser/rollup.config.js | 6 ------ 2 files changed, 7 deletions(-) diff --git a/packages/browser/package.json b/packages/browser/package.json index a9da1ba01f6d..d6e16096e230 100644 --- a/packages/browser/package.json +++ b/packages/browser/package.json @@ -43,7 +43,6 @@ "rollup": "^1.10.1", "rollup-plugin-commonjs": "^9.3.4", "rollup-plugin-license": "^0.8.1", - "rollup-plugin-modify": "^3.0.0", "rollup-plugin-node-resolve": "^4.2.3", "rollup-plugin-terser": "^4.0.4", "rollup-plugin-typescript2": "^0.21.0", diff --git a/packages/browser/rollup.config.js b/packages/browser/rollup.config.js index 40de2af457cd..12f738018a81 100644 --- a/packages/browser/rollup.config.js +++ b/packages/browser/rollup.config.js @@ -3,7 +3,6 @@ import typescript from 'rollup-plugin-typescript2'; import license from 'rollup-plugin-license'; import resolve from 'rollup-plugin-node-resolve'; import commonjs from 'rollup-plugin-commonjs'; -import modify from 'rollup-plugin-modify'; const commitHash = require('child_process') .execSync('git rev-parse --short HEAD', { encoding: 'utf-8' }) @@ -47,11 +46,6 @@ const plugins = [ mainFields: ['module'], }), commonjs(), - modify({ - // It's very difficult to use Symbol without polyfilling in IE10 and still making TypeScript behave correctly. - // Just remove it and leave this space in there, so that SourceMaps are still correct. - "this[Symbol.toStringTag] = '[object SyncPromise]';": ' ', - }), ]; const bundleConfig = {