Skip to content

Commit 551021f

Browse files
HazATkamilogorek
authored andcommitted
feat: Add simple request queue with close function (#1504)
* ref: Rename send on transport to captureEvent * feat: Add basic queue implementation * feat: Add queue to backends and client + reason of skip * fix: Tests * fix: Typo * fix: Integration tests * Fixed integration tests * fix: Rename queue to transportbuffer
1 parent fe631bf commit 551021f

File tree

23 files changed

+288
-37
lines changed

23 files changed

+288
-37
lines changed

packages/browser/src/backend.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Backend, logger, Options, SentryError } from '@sentry/core';
1+
import { Backend, logger, Options, SentryError, TransportBuffer } from '@sentry/core';
22
import { SentryEvent, SentryEventHint, SentryResponse, Severity, Status, Transport } from '@sentry/types';
33
import { isDOMError, isDOMException, isError, isErrorEvent, isPlainObject } from '@sentry/utils/is';
44
import { supportsBeacon, supportsFetch } from '@sentry/utils/supports';
@@ -40,6 +40,9 @@ export class BrowserBackend implements Backend {
4040
/** Cached transport used internally. */
4141
private transport?: Transport;
4242

43+
/** A simple buffer holding all requests. */
44+
private readonly buffer: TransportBuffer<SentryResponse> = new TransportBuffer();
45+
4346
/**
4447
* @inheritDoc
4548
*/
@@ -141,8 +144,8 @@ export class BrowserBackend implements Backend {
141144
public async sendEvent(event: SentryEvent): Promise<SentryResponse> {
142145
if (!this.options.dsn) {
143146
logger.warn(`Event has been skipped because no Dsn is configured.`);
144-
// We do nothing in case there is no Dsn
145-
return { status: Status.Skipped };
147+
// We do nothing in case there is no DSN
148+
return { status: Status.Skipped, reason: `Event has been skipped because no Dsn is configured.` };
146149
}
147150

148151
if (!this.transport) {
@@ -161,7 +164,7 @@ export class BrowserBackend implements Backend {
161164
}
162165
}
163166

164-
return this.transport.send(event);
167+
return this.buffer.add(this.transport.captureEvent(event));
165168
}
166169

167170
/**
@@ -177,4 +180,11 @@ export class BrowserBackend implements Backend {
177180
public storeScope(): void {
178181
// Noop
179182
}
183+
184+
/**
185+
* @inheritDoc
186+
*/
187+
public async close(timeout?: number): Promise<boolean> {
188+
return this.buffer.drain(timeout);
189+
}
180190
}

packages/browser/src/transports/base.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export abstract class BaseTransport implements Transport {
1515
/**
1616
* @inheritDoc
1717
*/
18-
public async send(_: SentryEvent): Promise<SentryResponse> {
19-
throw new SentryError('Transport Class has to implement `send` method');
18+
public async captureEvent(_: SentryEvent): Promise<SentryResponse> {
19+
throw new SentryError('Transport Class has to implement `captureEvent` method');
2020
}
2121
}

packages/browser/src/transports/beacon.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export class BeaconTransport extends BaseTransport {
1010
/**
1111
* @inheritDoc
1212
*/
13-
public async send(event: SentryEvent): Promise<SentryResponse> {
13+
public async captureEvent(event: SentryEvent): Promise<SentryResponse> {
1414
const data = serialize(event);
1515

1616
const result = global.navigator.sendBeacon(this.url, data);

packages/browser/src/transports/fetch.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export class FetchTransport extends BaseTransport {
1111
/**
1212
* @inheritDoc
1313
*/
14-
public async send(event: SentryEvent): Promise<SentryResponse> {
14+
public async captureEvent(event: SentryEvent): Promise<SentryResponse> {
1515
const defaultOptions: RequestInit = {
1616
body: serialize(event),
1717
method: 'POST',

packages/browser/src/transports/xhr.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export class XHRTransport extends BaseTransport {
77
/**
88
* @inheritDoc
99
*/
10-
public async send(event: SentryEvent): Promise<SentryResponse> {
10+
public async captureEvent(event: SentryEvent): Promise<SentryResponse> {
1111
return new Promise<SentryResponse>((resolve, reject) => {
1212
const request = new XMLHttpRequest();
1313

packages/browser/test/backend.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { BrowserBackend } from '../src/backend';
44
import { BaseTransport } from '../src/transports';
55

66
class SimpleTransport extends BaseTransport {
7-
public async send(_: SentryEvent): Promise<SentryResponse> {
7+
public async captureEvent(_: SentryEvent): Promise<SentryResponse> {
88
return {
99
status: Status.fromHttpCode(200),
1010
};
@@ -34,7 +34,7 @@ describe('BrowserBackend', () => {
3434
}
3535
});
3636

37-
it('should call send() on provided transport', async () => {
37+
it('should call captureEvent() on provided transport', async () => {
3838
backend = new BrowserBackend({ dsn, transport: SimpleTransport });
3939
const status = await backend.sendEvent(testEvent);
4040
expect(status.status).equal(Status.Success);

packages/browser/test/integration/frame.html

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,19 +110,25 @@
110110

111111
// stub transport so we don't actually transmit any data
112112
function DummyTransport() { }
113-
DummyTransport.prototype.send = function (event) {
113+
DummyTransport.prototype.captureEvent = function (event) {
114114
// console.log(JSON.stringify(event, null, 2));
115115
sentryData.push(event);
116-
return {
116+
return Promise.resolve({
117117
status: 'success'
118-
}
118+
})
119119
}
120120

121121
Sentry.init({
122122
dsn: 'https://[email protected]/1',
123123
attachStacktrace: true,
124124
transport: DummyTransport,
125125
beforeBreadcrumb: function (breadcrumb) {
126+
// Filter console logs as we use them for debugging *a lot* and they are not *that* important
127+
if (breadcrumb.category === 'console') { return null }
128+
129+
// overlyComplicatedDebuggingMechanism 'aka' console.log driven debugging
130+
// console.log(JSON.stringify(breadcrumb, null, 2));
131+
126132
// Filter internal Karma requests
127133
if (
128134
breadcrumb.type === 'http' &&

packages/browser/test/integration/test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ describe('integration', function() {
766766
done,
767767
function() {
768768
var xhr = new XMLHttpRequest();
769-
xhr.open('GET', 'https://public@example.com/1/store');
769+
xhr.open('GET', 'https://example.com/api/1/store/');
770770
xhr.send('{"message":"someMessage","level":"warning"}');
771771
setTimeout(done);
772772
},

packages/browser/test/transports/base.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@ const testDsn = 'https://[email protected]/42';
66
class SimpleTransport extends BaseTransport {}
77

88
describe('BaseTransport', () => {
9-
it('doesnt provide send() implementation', async () => {
9+
it('doesnt provide captureEvent() implementation', async () => {
1010
const transport = new SimpleTransport({ dsn: testDsn });
1111

1212
try {
13-
await transport.send({});
13+
await transport.captureEvent({});
1414
} catch (e) {
15-
expect(e.message).equal('Transport Class has to implement `send` method');
15+
expect(e.message).equal('Transport Class has to implement `captureEvent` method');
1616
}
1717
});
1818

packages/browser/test/transports/beacon.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ describe('BeaconTransport', () => {
2929
expect(transport.url).equal(transportUrl);
3030
});
3131

32-
describe('send()', async () => {
32+
describe('captureEvent()', async () => {
3333
it('sends a request to Sentry servers', async () => {
3434
sendBeacon.returns(true);
3535

36-
return transport.send(payload).then(res => {
36+
return transport.captureEvent(payload).then(res => {
3737
expect(res.status).equal(Status.Success);
3838
expect(sendBeacon.calledOnce).equal(true);
3939
expect(sendBeacon.calledWith(transportUrl, JSON.stringify(payload))).equal(true);
@@ -43,7 +43,7 @@ describe('BeaconTransport', () => {
4343
it('rejects with failed status', async () => {
4444
sendBeacon.returns(false);
4545

46-
return transport.send(payload).catch(res => {
46+
return transport.captureEvent(payload).catch(res => {
4747
expect(res.status).equal(Status.Failed);
4848
expect(sendBeacon.calledOnce).equal(true);
4949
expect(sendBeacon.calledWith(transportUrl, JSON.stringify(payload))).equal(true);

0 commit comments

Comments
 (0)