Skip to content

Commit ae2f1ce

Browse files
committed
feat: Introduce SentryResponse, Status, move to types
Add node transports
1 parent 3a0ec5d commit ae2f1ce

File tree

19 files changed

+306
-117
lines changed

19 files changed

+306
-117
lines changed

packages/browser/src/backend.ts

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Backend, DSN, Options, SentryError } from '@sentry/core';
22
import { addBreadcrumb, captureEvent } from '@sentry/minimal';
3-
import { SentryEvent } from '@sentry/types';
3+
import { SentryEvent, SentryResponse } from '@sentry/types';
44
import { supportsFetch } from '@sentry/utils/supports';
55
import { Raven } from './raven';
66
import { FetchTransport, XHRTransport } from './transports';
@@ -115,7 +115,7 @@ export class BrowserBackend implements Backend {
115115
/**
116116
* @inheritDoc
117117
*/
118-
public async sendEvent(event: SentryEvent): Promise<number> {
118+
public async sendEvent(event: SentryEvent): Promise<SentryResponse> {
119119
let dsn: DSN;
120120

121121
if (!this.options.dsn) {
@@ -130,10 +130,7 @@ export class BrowserBackend implements Backend {
130130
? new FetchTransport({ dsn })
131131
: new XHRTransport({ dsn });
132132

133-
return transport
134-
.send(event)
135-
.then((response: Response | XMLHttpRequest) => response.status)
136-
.catch((error: Response | XMLHttpRequest) => error.status);
133+
return transport.send(event);
137134
}
138135

139136
/**

packages/browser/src/client.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export class BrowserClient extends BaseClient<BrowserBackend, BrowserOptions> {
3232
/**
3333
* Instruments the given function and sends an event to Sentry every time the
3434
* function throws an exception.
35+
* TODO remove this
3536
*
3637
* @param fn A function to wrap.
3738
* @returns The wrapped function.

packages/browser/src/index.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ export {
44
SdkInfo,
55
SentryEvent,
66
SentryException,
7+
SentryResponse,
78
Severity,
89
StackFrame,
910
Stacktrace,
11+
Status,
1012
Thread,
1113
User,
1214
} from '@sentry/types';
@@ -27,3 +29,6 @@ export { init } from './sdk';
2729

2830
import * as Integrations from './integrations';
2931
export { Integrations };
32+
33+
import * as Transports from './transports';
34+
export { Transports };

packages/browser/src/transports/base.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { DSN, SentryError } from '@sentry/core';
22
import {
33
DSNComponents,
44
SentryEvent,
5+
SentryResponse,
56
Transport,
67
TransportOptions,
78
} from '@sentry/types';
@@ -49,7 +50,7 @@ export abstract class BaseTransport implements Transport {
4950
/**
5051
* @inheritDoc
5152
*/
52-
public async send(_: SentryEvent): Promise<Response | XMLHttpRequest> {
53+
public async send(_: SentryEvent): Promise<SentryResponse> {
5354
throw new SentryError('Transport Class has to implement `send` method');
5455
}
5556
}

packages/browser/src/transports/fetch.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { SentryEvent } from '@sentry/types';
1+
import { SentryEvent, SentryResponse, Status } from '@sentry/types';
22
import { getGlobalObject } from '@sentry/utils/misc';
33
import { serialize } from '@sentry/utils/object';
44
import { supportsReferrerPolicy } from '@sentry/utils/supports';
@@ -11,7 +11,7 @@ export class FetchTransport extends BaseTransport {
1111
/**
1212
* @inheritDoc
1313
*/
14-
public async send(event: SentryEvent): Promise<Response> {
14+
public async send(event: SentryEvent): Promise<SentryResponse> {
1515
const defaultOptions: RequestInit = {
1616
body: serialize(event),
1717
keepalive: true,
@@ -25,6 +25,12 @@ export class FetchTransport extends BaseTransport {
2525
: '') as ReferrerPolicy,
2626
};
2727

28-
return (global as Window).fetch(this.url, defaultOptions);
28+
const response = await (global as Window).fetch(this.url, defaultOptions);
29+
30+
return {
31+
code: response.status,
32+
event_id: event.event_id,
33+
status: Status.fromHttpCode(response.status),
34+
};
2935
}
3036
}

packages/browser/src/transports/xhr.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { SentryEvent } from '@sentry/types';
1+
import { SentryEvent, SentryResponse, Status } from '@sentry/types';
22
import { serialize } from '@sentry/utils/object';
33
import { BaseTransport } from './base';
44

@@ -7,8 +7,8 @@ export class XHRTransport extends BaseTransport {
77
/**
88
* @inheritDoc
99
*/
10-
public async send(event: SentryEvent): Promise<XMLHttpRequest> {
11-
return new Promise<XMLHttpRequest>((resolve, reject) => {
10+
public async send(event: SentryEvent): Promise<SentryResponse> {
11+
return new Promise<SentryResponse>((resolve, reject) => {
1212
const request = new XMLHttpRequest();
1313

1414
request.onreadystatechange = () => {
@@ -17,7 +17,11 @@ export class XHRTransport extends BaseTransport {
1717
}
1818

1919
if (request.status === 200) {
20-
resolve(request);
20+
resolve({
21+
code: request.status,
22+
event_id: event.event_id,
23+
status: Status.fromHttpCode(request.status),
24+
});
2125
}
2226

2327
reject(request);

packages/browser/test/backend.test.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
import { expect } from 'chai';
2-
import { SentryEvent } from '../src';
2+
import { SentryEvent, SentryResponse, Status } from '../src';
33
import { BrowserBackend } from '../src/backend';
44
import { BaseTransport } from '../src/transports';
55

66
class SimpleTransport extends BaseTransport {
7-
public async send(event: SentryEvent): Promise<Response> {
8-
return new Response(event.event_id, {
9-
status: 200,
10-
});
7+
public async send(event: SentryEvent): Promise<SentryResponse> {
8+
return {
9+
code: 200,
10+
event_id: event.event_id,
11+
status: Status.fromHttpCode(200),
12+
};
1113
}
1214
}
1315

@@ -37,7 +39,7 @@ describe('BrowserBackend', () => {
3739
it('should call send() on provided transport', async () => {
3840
backend = new BrowserBackend({ dsn, transport: SimpleTransport });
3941
const status = await backend.sendEvent(testEvent);
40-
expect(status).equal(200);
42+
expect(status.code).equal(200);
4143
});
4244
});
4345
});

packages/browser/test/transports/fetch.test.ts

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import { Transport } from '@sentry/types';
21
import { expect } from 'chai';
32
import { SinonStub, stub } from 'sinon';
4-
import { FetchTransport } from '../../src/transports/fetch';
3+
import { Status, Transports } from '../../src';
54

65
const testDSN = 'https://[email protected]/42';
76
const transportUrl =
@@ -15,12 +14,12 @@ const payload = {
1514
};
1615

1716
let fetch: SinonStub;
18-
let transport: Transport;
17+
let transport: Transports.BaseTransport;
1918

2019
describe('FetchTransport', () => {
2120
beforeEach(() => {
2221
fetch = stub(window, 'fetch');
23-
transport = new FetchTransport({ dsn: testDSN });
22+
transport = new Transports.FetchTransport({ dsn: testDSN });
2423
});
2524

2625
afterEach(() => {
@@ -33,14 +32,13 @@ describe('FetchTransport', () => {
3332

3433
describe('send()', async () => {
3534
it('sends a request to Sentry servers', async () => {
36-
const response = new Response('', {
37-
status: 200,
38-
});
35+
const response = { status: 200 };
3936

4037
fetch.returns(Promise.resolve(response));
4138

4239
return transport.send(payload).then(res => {
43-
expect(res.status).equal(200);
40+
expect(res.code).equal(200);
41+
expect(res.status).equal(Status.Success);
4442
expect(fetch.calledOnce).equal(true);
4543
expect(
4644
fetch.calledWith(transportUrl, {
@@ -54,9 +52,7 @@ describe('FetchTransport', () => {
5452
});
5553

5654
it('rejects with non-200 status code', async () => {
57-
const response = new Response('', {
58-
status: 403,
59-
});
55+
const response = { status: 403 };
6056

6157
fetch.returns(Promise.reject(response));
6258

packages/browser/test/transports/xhr.test.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import { Transport } from '@sentry/types';
21
import { expect } from 'chai';
32
import { fakeServer, SinonFakeServer } from 'sinon';
4-
import { XHRTransport } from '../../src/transports/xhr';
3+
import { Transports } from '../../src';
54

65
const testDSN = 'https://[email protected]/42';
76
const transportUrl =
@@ -15,13 +14,13 @@ const payload = {
1514
};
1615

1716
let server: SinonFakeServer;
18-
let transport: Transport;
17+
let transport: Transports.BaseTransport;
1918

2019
describe('XHRTransport', () => {
2120
beforeEach(() => {
2221
server = fakeServer.create();
2322
server.respondImmediately = true;
24-
transport = new XHRTransport({ dsn: testDSN });
23+
transport = new Transports.XHRTransport({ dsn: testDSN });
2524
});
2625

2726
afterEach(() => {
@@ -37,7 +36,7 @@ describe('XHRTransport', () => {
3736
server.respondWith('POST', transportUrl, [200, {}, '']);
3837

3938
return transport.send(payload).then(res => {
40-
expect(res.status).equal(200);
39+
expect(res.code).equal(200);
4140

4241
const request = server.requests[0];
4342
expect(server.requests.length).equal(1);
@@ -46,16 +45,17 @@ describe('XHRTransport', () => {
4645
});
4746
});
4847

49-
it('rejects with non-200 status code', async () => {
48+
it('rejects with non-200 status code', done => {
5049
server.respondWith('POST', transportUrl, [403, {}, '']);
5150

52-
return transport.send(payload).catch(res => {
51+
transport.send(payload).catch(res => {
5352
expect(res.status).equal(403);
5453

5554
const request = server.requests[0];
5655
expect(server.requests.length).equal(1);
5756
expect(request.method).equal('POST');
5857
expect(JSON.parse(request.requestBody)).deep.equal(payload);
58+
done();
5959
});
6060
});
6161
});

packages/core/src/base.ts

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
import { Scope } from '@sentry/hub';
2-
import { Breadcrumb, SdkInfo, SentryEvent } from '@sentry/types';
2+
import {
3+
Breadcrumb,
4+
SdkInfo,
5+
SentryEvent,
6+
SentryResponse,
7+
Status,
8+
} from '@sentry/types';
39
import { uuid4 } from '@sentry/utils/misc';
410
import { truncate } from '@sentry/utils/string';
511
import { DSN } from './dsn';
612
import { Backend, Client, Options } from './interfaces';
7-
import { SendStatus } from './status';
813

914
/**
1015
* Default maximum number of breadcrumbs added to an event. Can be overwritten
@@ -136,8 +141,11 @@ export abstract class BaseClient<B extends Backend, O extends Options>
136141
/**
137142
* @inheritDoc
138143
*/
139-
public async captureEvent(event: SentryEvent, scope?: Scope): Promise<void> {
140-
await this.processEvent(
144+
public async captureEvent(
145+
event: SentryEvent,
146+
scope?: Scope,
147+
): Promise<SentryResponse> {
148+
return this.processEvent(
141149
event,
142150
async finalEvent => this.getBackend().sendEvent(finalEvent),
143151
scope,
@@ -290,38 +298,45 @@ export abstract class BaseClient<B extends Backend, O extends Options>
290298
*/
291299
protected async processEvent(
292300
event: SentryEvent,
293-
send: (finalEvent: SentryEvent) => Promise<number>,
301+
send: (finalEvent: SentryEvent) => Promise<SentryResponse>,
294302
scope?: Scope,
295-
): Promise<SendStatus> {
303+
): Promise<SentryResponse> {
296304
if (!this.isEnabled()) {
297-
return SendStatus.Skipped;
305+
return {
306+
code: -1,
307+
event_id: event.event_id,
308+
status: Status.Skipped,
309+
};
298310
}
299311

300312
const prepared = await this.prepareEvent(event, scope);
301313
const { shouldSend, beforeSend, afterSend } = this.getOptions();
302314
if (shouldSend && !shouldSend(prepared)) {
303-
return SendStatus.Skipped;
315+
return {
316+
code: -1,
317+
event_id: event.event_id,
318+
status: Status.Skipped,
319+
};
304320
}
305321

306322
// TODO: Add breadcrumb with our own event?
307323
// Or should it be handled by the xhr/fetch integration itself?
308324
// Or maybe some other integration that'd use `afterSend`?
309325

310326
const finalEvent = beforeSend ? beforeSend(prepared) : prepared;
311-
const code = await send(finalEvent);
312-
const status = SendStatus.fromHttpCode(code);
327+
const response = await send(finalEvent);
313328

314-
if (status === SendStatus.RateLimit) {
329+
if (response.status === Status.RateLimit) {
315330
// TODO: Handle rate limits and maintain a queue. For now, we require SDK
316331
// implementors to override this method and handle it themselves.
317332
}
318333

319334
// TODO: Handle duplicates and backoffs
320335

321336
if (afterSend) {
322-
afterSend(finalEvent, status);
337+
afterSend(finalEvent, response);
323338
}
324339

325-
return status;
340+
return response;
326341
}
327342
}

packages/core/src/interfaces.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ import {
33
Breadcrumb,
44
Integration,
55
SentryEvent,
6+
SentryResponse,
67
Transport,
78
TransportClass,
89
} from '@sentry/types';
910
import { DSN } from './dsn';
10-
import { SendStatus } from './status';
1111

1212
/** Console logging verbosity for the SDK. */
1313
export enum LogLevel {
@@ -100,7 +100,7 @@ export interface Options {
100100
* A callback invoked after event submission has completed.
101101
* @param event The error or message event sent to Sentry.
102102
*/
103-
afterSend?(event: SentryEvent, status: SendStatus): void;
103+
afterSend?(event: SentryEvent, status: SentryResponse): void;
104104

105105
/**
106106
* A callback allowing to skip breadcrumbs.
@@ -191,7 +191,7 @@ export interface Client<O extends Options = Options> {
191191
* @param scope An optional scope containing event metadata.
192192
* @returns The created event id.
193193
*/
194-
captureEvent(event: SentryEvent, scope?: Scope): Promise<void>;
194+
captureEvent(event: SentryEvent, scope?: Scope): Promise<SentryResponse>;
195195

196196
/**
197197
* Records a new breadcrumb which will be attached to future events.
@@ -244,7 +244,7 @@ export interface Backend {
244244
eventFromMessage(message: string): Promise<SentryEvent>;
245245

246246
/** Submits the event to Sentry */
247-
sendEvent(event: SentryEvent): Promise<number>;
247+
sendEvent(event: SentryEvent): Promise<SentryResponse>;
248248

249249
/**
250250
* Receives a breadcrumb and stores it in a platform-dependent way.

0 commit comments

Comments
 (0)