Skip to content

Commit 70797ca

Browse files
committed
[v7] TransportOptions, CA Certificates and Transport types unification
1 parent 11de1ad commit 70797ca

File tree

14 files changed

+168
-253
lines changed

14 files changed

+168
-253
lines changed

packages/core/src/baseclient.ts

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ import {
88
ScopeLike,
99
SessionStatus,
1010
Integration,
11+
TransportRequest,
12+
Transport,
1113
} from '@sentry/types';
1214
import {
1315
dateTimestampInSeconds,
@@ -19,14 +21,7 @@ import {
1921
truncate,
2022
uuid4,
2123
} from '@sentry/utils';
22-
import {
23-
Dsn,
24-
eventToTransportRequest,
25-
NoopTransport,
26-
sessionToTransportRequest,
27-
TransportRequest,
28-
Transport,
29-
} from '@sentry/transport-base';
24+
import { Dsn, eventToTransportRequest, NoopTransport, sessionToTransportRequest } from '@sentry/transport-base';
3025

3126
import { collectIntegrations } from './integrations';
3227

@@ -91,17 +86,20 @@ export abstract class BaseClient<O extends Options> implements ClientLike<O> {
9186
*/
9287
protected constructor(options: O) {
9388
this.options = options ?? {};
89+
this.logger.enabled = !!this.options.debug;
9490

9591
if (this.options.dsn) {
9692
this.dsn = new Dsn(this.options.dsn);
9793
}
9894

99-
if (this.options.debug) {
100-
this.logger.enabled = true;
101-
}
102-
10395
this._scope = this.options._internal?.scope || new Scope();
104-
this._transport = this._setupTransport();
96+
this._transport =
97+
!this.options.dsn || !this.options.transport
98+
? new NoopTransport()
99+
: new this.options.transport({
100+
dsn: this.options.dsn,
101+
...this.options.transportOptions,
102+
});
105103
this._integrations = this._setupIntegrations();
106104
}
107105

@@ -117,7 +115,6 @@ export abstract class BaseClient<O extends Options> implements ClientLike<O> {
117115
this._scope = scope;
118116
}
119117

120-
// TODO: Run these during event processing
121118
public addEventProcessor(callback: EventProcessor): void {
122119
this._eventProcessors.push(callback);
123120
}
@@ -187,22 +184,6 @@ export abstract class BaseClient<O extends Options> implements ClientLike<O> {
187184
});
188185
}
189186

190-
protected _setupTransport(): Transport {
191-
// TODO: This whole function should be unnecessary and moved to client construction
192-
if (!this.options.dsn || !this.options.transport) {
193-
return new NoopTransport();
194-
}
195-
196-
return new this.options.transport({
197-
dsn: this.options.dsn,
198-
...this.options.transportOptions,
199-
// TODO: Deprecate these options and move to `transportOptions`
200-
// ...(this.options.httpProxy && { httpProxy: this.options.httpProxy }),
201-
// ...(this.options.httpsProxy && { httpsProxy: this.options.httpsProxy }),
202-
// ...(this.options.caCerts && { caCerts: this.options.caCerts }),
203-
});
204-
}
205-
206187
protected _setupIntegrations(): Record<string, Integration> {
207188
const integrations = collectIntegrations({
208189
defaultIntegrations: this.options.defaultIntegrations ? this.options._internal?.defaultIntegrations : [],
@@ -419,6 +400,7 @@ export abstract class BaseClient<O extends Options> implements ClientLike<O> {
419400
event: processedEvent,
420401
},
421402
);
403+
422404
return processedEvent.event_id;
423405
}
424406

packages/eventbuilder-browser/src/index.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@ import {
1515
import { eventFromPlainObject, eventFromStacktrace, prepareFramesForEvent } from './parsers';
1616
import { computeStackTrace } from './tracekit';
1717

18-
// TODO: Export only necessary thing. Or nothing at all directly from parsers/tracekit.
19-
export * from './tracekit';
20-
export * from './parsers';
18+
export { exceptionFromStacktrace } from './parsers';
19+
export { computeStackTrace } from './tracekit';
2120

2221
/**
2322
* Builds and SentryEvent from a Exception

packages/integration-common-inboundfilters/src/index.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ export class InboundFilters implements Integration {
101101
}
102102

103103
private _isDeniedUrl(event: SentryEvent, options: Partial<InboundFiltersOptions>): boolean {
104-
// TODO: Use Glob instead?
105104
if (!options.denyUrls || !options.denyUrls.length) {
106105
return false;
107106
}
@@ -110,7 +109,6 @@ export class InboundFilters implements Integration {
110109
}
111110

112111
private _isAllowedUrl(event: SentryEvent, options: Partial<InboundFiltersOptions>): boolean {
113-
// TODO: Use Glob instead?
114112
if (!options.allowUrls || !options.allowUrls.length) {
115113
return true;
116114
}
@@ -127,7 +125,6 @@ export class InboundFilters implements Integration {
127125
...(clientOptions.ignoreErrors || []),
128126
...DEFAULT_IGNORE_ERRORS,
129127
],
130-
// TODO: Do we ever used it? Like ever? - https://github.com/getsentry/sentry-javascript/search?q=ignoreInternal
131128
ignoreInternal: typeof this._options.ignoreInternal !== 'undefined' ? this._options.ignoreInternal : true,
132129
};
133130
}

packages/node/src/client.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,6 @@ export interface NodeOptions extends Options {
1616
/** Maximum time in milliseconds to wait to drain the request queue, before the process is allowed to exit. */
1717
shutdownTimeout?: number;
1818

19-
/** Set a HTTP proxy that should be used for outbound requests. */
20-
httpProxy?: string;
21-
22-
/** Set a HTTPS proxy that should be used for outbound requests. */
23-
httpsProxy?: string;
24-
25-
/** HTTPS proxy certificates path */
26-
caCerts?: string;
27-
2819
/** Sets the number of context lines for each frame when loading a file. */
2920
frameContextLines?: number;
3021

packages/tracing/src/transaction.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
Transaction as TransactionInterface,
66
TransactionContext,
77
ClientLike,
8+
EventType,
89
} from '@sentry/types';
910
import { dropUndefinedKeys } from '@sentry/utils';
1011

@@ -118,7 +119,7 @@ export class Transaction extends SpanClass implements TransactionInterface {
118119
tags: this.tags,
119120
timestamp: this.endTimestamp,
120121
transaction: this.name,
121-
type: 'transaction',
122+
type: EventType.Transaction,
122123
debug_meta: this._metadata,
123124
};
124125

packages/transport-base/src/index.ts

Lines changed: 4 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,4 @@
1-
import { Dsn, getReportDialogEndpoint, ReportDialogOptions } from './dsn';
2-
import { isRateLimited, updateRateLimits, RateLimits, disabledUntil } from './rateLimit';
3-
import { AsyncBuffer } from './asyncBuffer';
4-
import { ResponseStatus, responseStatusFromStatusCode } from './responseStatus';
5-
import {
6-
EventType,
7-
TransportRequest,
8-
TransportResponse,
9-
TransportMakerResponse,
10-
TransportRequestMaker,
11-
sessionToTransportRequest,
12-
eventToTransportRequest,
13-
} from './requestBuilder';
14-
15-
// Classes & Functions
16-
export { Dsn, getReportDialogEndpoint, sessionToTransportRequest, eventToTransportRequest };
17-
18-
// Types
19-
export {
20-
EventType,
21-
ReportDialogOptions,
22-
ResponseStatus,
23-
TransportRequest,
24-
TransportResponse,
25-
TransportMakerResponse,
26-
TransportRequestMaker,
27-
};
28-
29-
// Transport generic over `T` allows us to use `Buffer` type for streaming requests in environments like Electron.
30-
export interface Transport {
31-
sendRequest<T>(request: TransportRequest<T>): PromiseLike<TransportResponse>;
32-
flush(timeout: number): PromiseLike<boolean>;
33-
}
34-
35-
// TODO: Unify all transports options
36-
export type TransportOptions = {
37-
// TODO: Restore `string | Dsn` once we get rid of Transport in @sentry/types
38-
dsn: string;
39-
bufferSize?: number;
40-
headers?: Record<string, string>;
41-
};
42-
43-
export abstract class BaseTransport {
44-
protected readonly _dsn: Dsn;
45-
protected readonly _asyncBuffer: AsyncBuffer<TransportResponse>;
46-
protected _rateLimits: RateLimits = {};
47-
48-
public constructor(public options: TransportOptions) {
49-
this._dsn = new Dsn(this.options.dsn);
50-
// this._dsn = typeof this.options.dsn === 'string' ? new Dsn(this.options.dsn) : this.options.dsn;
51-
this._asyncBuffer = new AsyncBuffer(this.options.bufferSize ?? 30);
52-
}
53-
54-
public sendRequest<T>(
55-
request: TransportRequest<T>,
56-
requestMaker: TransportRequestMaker<T>,
57-
): PromiseLike<TransportResponse> {
58-
if (isRateLimited(this._rateLimits, request.type)) {
59-
// TODO: Use SentryError
60-
return Promise.reject(
61-
new Error(
62-
`Transport for \`${request.type}\` locked till ${disabledUntil(
63-
this._rateLimits,
64-
request.type,
65-
)} due to too many requests.`,
66-
),
67-
);
68-
}
69-
70-
/**
71-
* We need to create a request _only_ once it's called.
72-
* This makes sure that requests are correctly dropped,
73-
* and they are not making any network calls when the buffer is full.
74-
*/
75-
const sendRequestTask = (): PromiseLike<TransportResponse> => {
76-
return requestMaker(request).then(
77-
({ body, headers, statusCode, reason }): PromiseLike<TransportResponse> => {
78-
if (headers) {
79-
this._rateLimits = updateRateLimits(this._rateLimits, headers);
80-
}
81-
82-
const status = responseStatusFromStatusCode(statusCode);
83-
84-
if (status === ResponseStatus.Success) {
85-
return Promise.resolve({ status });
86-
}
87-
88-
// TODO: Use SentryError
89-
return Promise.reject(new Error(body ?? reason ?? 'Unknown transport error'));
90-
},
91-
);
92-
};
93-
94-
return this._asyncBuffer.add(sendRequestTask);
95-
}
96-
97-
// TODO: Make requestMaker an abstract method that has to be implemented by the class that extends it?
98-
99-
public flush(timeout: number = 0): PromiseLike<boolean> {
100-
return this._asyncBuffer.drain(timeout);
101-
}
102-
}
103-
104-
export class NoopTransport implements Transport {
105-
public sendRequest(_request: TransportRequest<unknown>): PromiseLike<TransportResponse> {
106-
return Promise.resolve({
107-
reason: `NoopTransport: SentryEvent has been skipped because no Dsn is configured.`,
108-
status: ResponseStatus.Skipped,
109-
});
110-
}
111-
112-
public flush(_timeout: number): PromiseLike<boolean> {
113-
return Promise.resolve(true);
114-
}
115-
}
1+
export { BaseTransport, NoopTransport } from './transport';
2+
export { Dsn, getReportDialogEndpoint, ReportDialogOptions } from './dsn';
3+
export { ResponseStatus } from './responseStatus';
4+
export { sessionToTransportRequest, eventToTransportRequest } from './requestBuilder';

packages/transport-base/src/requestBuilder.ts

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,4 @@
1-
import { SentryEvent, Session } from '@sentry/types';
2-
3-
import { ResponseStatus } from './responseStatus';
4-
5-
export type TransportRequest<T> = {
6-
body: T;
7-
type: EventType;
8-
};
9-
10-
export type TransportResponse = {
11-
status: ResponseStatus;
12-
reason?: string;
13-
};
14-
15-
export type TransportMakerResponse = {
16-
body?: string;
17-
headers?: Record<string, string | null>;
18-
reason?: string;
19-
statusCode: number;
20-
};
21-
22-
export type TransportRequestMaker<T> = (request: TransportRequest<T>) => PromiseLike<TransportMakerResponse>;
23-
24-
export enum EventType {
25-
Error = 'error',
26-
Session = 'session',
27-
Transaction = 'transaction',
28-
}
1+
import { EventType, SentryEvent, Session, TransportRequest } from '@sentry/types';
292

303
/**
314
* Apply SdkInfo (name, version, packages, integrations) to the corresponding event key.
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { Transport, TransportOptions, TransportResponse, TransportRequest, TransportRequestMaker } from '@sentry/types';
2+
3+
import { Dsn } from './dsn';
4+
import { isRateLimited, updateRateLimits, RateLimits, disabledUntil } from './rateLimit';
5+
import { AsyncBuffer } from './asyncBuffer';
6+
import { ResponseStatus, responseStatusFromStatusCode } from './responseStatus';
7+
8+
export abstract class BaseTransport {
9+
protected readonly _dsn: Dsn;
10+
protected readonly _asyncBuffer: AsyncBuffer<TransportResponse>;
11+
protected _rateLimits: RateLimits = {};
12+
13+
public constructor(public options: TransportOptions) {
14+
this._dsn = new Dsn(this.options.dsn);
15+
// this._dsn = typeof this.options.dsn === 'string' ? new Dsn(this.options.dsn) : this.options.dsn;
16+
this._asyncBuffer = new AsyncBuffer(this.options.bufferSize ?? 30);
17+
}
18+
19+
public sendRequest<T>(
20+
request: TransportRequest<T>,
21+
requestMaker: TransportRequestMaker<T>,
22+
): PromiseLike<TransportResponse> {
23+
if (isRateLimited(this._rateLimits, request.type)) {
24+
// TODO: Use SentryError
25+
return Promise.reject(
26+
new Error(
27+
`Transport for \`${request.type}\` locked till ${disabledUntil(
28+
this._rateLimits,
29+
request.type,
30+
)} due to too many requests.`,
31+
),
32+
);
33+
}
34+
35+
/**
36+
* We need to create a request _only_ once it's called.
37+
* This makes sure that requests are correctly dropped,
38+
* and they are not making any network calls when the buffer is full.
39+
*/
40+
const sendRequestTask = (): PromiseLike<TransportResponse> => {
41+
return requestMaker(request).then(
42+
({ body, headers, statusCode, reason }): PromiseLike<TransportResponse> => {
43+
if (headers) {
44+
this._rateLimits = updateRateLimits(this._rateLimits, headers);
45+
}
46+
47+
const status = responseStatusFromStatusCode(statusCode);
48+
49+
if (status === ResponseStatus.Success) {
50+
return Promise.resolve({ status });
51+
}
52+
53+
// TODO: Use SentryError
54+
return Promise.reject(new Error(body ?? reason ?? 'Unknown transport error'));
55+
},
56+
);
57+
};
58+
59+
return this._asyncBuffer.add(sendRequestTask);
60+
}
61+
62+
// TODO: Make requestMaker an abstract method that has to be implemented by the class that extends it?
63+
public flush(timeout: number = 0): PromiseLike<boolean> {
64+
return this._asyncBuffer.drain(timeout);
65+
}
66+
}
67+
68+
export class NoopTransport implements Transport {
69+
public sendRequest(_request: TransportRequest<unknown>): PromiseLike<TransportResponse> {
70+
return Promise.resolve({
71+
reason: `NoopTransport: SentryEvent has been skipped because no Dsn is configured.`,
72+
status: ResponseStatus.Skipped,
73+
});
74+
}
75+
76+
public flush(_timeout: number): PromiseLike<boolean> {
77+
return Promise.resolve(true);
78+
}
79+
}

0 commit comments

Comments
 (0)