Skip to content

Commit b9e44b9

Browse files
authored
feat(node): Support tunnel option for ANR (#11163)
Closes #11159 This PR also modifies `getEnvelopeEndpointWithUrlEncodedAuth` which had a suggested simplification for v8. I ignored the suggestion because `{ tunnel, _metadata }` feels like a very "internal" API. Sure, this is convenient because it lets you pass the client options directly but it doesn't sit right as a user facing API.
1 parent 4bbb853 commit b9e44b9

File tree

6 files changed

+27
-36
lines changed

6 files changed

+27
-36
lines changed

packages/core/src/api.ts

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { ClientOptions, DsnComponents, DsnLike, SdkInfo } from '@sentry/types';
1+
import type { DsnComponents, DsnLike, SdkInfo } from '@sentry/types';
22
import { dsnToString, makeDsn, urlEncode } from '@sentry/utils';
33

44
const SENTRY_API_VERSION = '7';
@@ -31,20 +31,7 @@ function _encodedAuth(dsn: DsnComponents, sdkInfo: SdkInfo | undefined): string
3131
*
3232
* Sending auth as part of the query string and not as custom HTTP headers avoids CORS preflight requests.
3333
*/
34-
export function getEnvelopeEndpointWithUrlEncodedAuth(
35-
dsn: DsnComponents,
36-
// TODO (v8): Remove `tunnelOrOptions` in favor of `options`, and use the substitute code below
37-
// options: ClientOptions = {} as ClientOptions,
38-
tunnelOrOptions: string | ClientOptions = {} as ClientOptions,
39-
): string {
40-
// TODO (v8): Use this code instead
41-
// const { tunnel, _metadata = {} } = options;
42-
// return tunnel ? tunnel : `${_getIngestEndpoint(dsn)}?${_encodedAuth(dsn, _metadata.sdk)}`;
43-
44-
const tunnel = typeof tunnelOrOptions === 'string' ? tunnelOrOptions : tunnelOrOptions.tunnel;
45-
const sdkInfo =
46-
typeof tunnelOrOptions === 'string' || !tunnelOrOptions._metadata ? undefined : tunnelOrOptions._metadata.sdk;
47-
34+
export function getEnvelopeEndpointWithUrlEncodedAuth(dsn: DsnComponents, tunnel?: string, sdkInfo?: SdkInfo): string {
4835
return tunnel ? tunnel : `${_getIngestEndpoint(dsn)}?${_encodedAuth(dsn, sdkInfo)}`;
4936
}
5037

packages/core/src/baseclient.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,11 @@ export abstract class BaseClient<O extends ClientOptions> implements Client<O> {
135135
}
136136

137137
if (this._dsn) {
138-
const url = getEnvelopeEndpointWithUrlEncodedAuth(this._dsn, options);
138+
const url = getEnvelopeEndpointWithUrlEncodedAuth(
139+
this._dsn,
140+
options.tunnel,
141+
options._metadata ? options._metadata.sdk : undefined,
142+
);
139143
this._transport = options.transport({
140144
recordDroppedEvent: this.recordDroppedEvent.bind(this),
141145
...options.transportOptions,

packages/core/test/lib/api.test.ts

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
import type { ClientOptions, DsnComponents } from '@sentry/types';
1+
import type { DsnComponents, SdkInfo } from '@sentry/types';
22
import { makeDsn } from '@sentry/utils';
33

44
import { getEnvelopeEndpointWithUrlEncodedAuth, getReportDialogEndpoint } from '../../src/api';
55

66
const ingestDsn = 'https://[email protected]:1234/subpath/123';
77
const dsnPublic = 'https://[email protected]:1234/subpath/123';
88
const tunnel = 'https://hello.com/world';
9-
const _metadata = { sdk: { name: 'sentry.javascript.browser', version: '12.31.12' } } as ClientOptions['_metadata'];
9+
const sdkInfo = { name: 'sentry.javascript.browser', version: '12.31.12' };
1010

1111
const dsnPublicComponents = makeDsn(dsnPublic)!;
1212

@@ -17,36 +17,34 @@ describe('API', () => {
1717
"doesn't include `sentry_client` when called with only DSN",
1818
dsnPublicComponents,
1919
undefined,
20+
undefined,
2021
'https://sentry.io:1234/subpath/api/123/envelope/?sentry_key=abc&sentry_version=7',
2122
],
22-
['uses `tunnel` value when called with `tunnel` as string', dsnPublicComponents, tunnel, tunnel],
23+
['uses `tunnel` value when called with `tunnel` option', dsnPublicComponents, tunnel, undefined, tunnel],
2324
[
24-
'uses `tunnel` value when called with `tunnel` in options',
25+
'uses `tunnel` value when called with `tunnel` and `sdkInfo` options',
2526
dsnPublicComponents,
26-
{ tunnel } as ClientOptions,
2727
tunnel,
28-
],
29-
[
30-
'uses `tunnel` value when called with `tunnel` and `_metadata` in options',
31-
dsnPublicComponents,
32-
{ tunnel, _metadata } as ClientOptions,
28+
sdkInfo,
3329
tunnel,
3430
],
3531
[
36-
'includes `sentry_client` when called with `_metadata` in options and no tunnel',
32+
'includes `sentry_client` when called with `sdkInfo` in options and no tunnel',
3733
dsnPublicComponents,
38-
{ _metadata } as ClientOptions,
34+
undefined,
35+
sdkInfo,
3936
'https://sentry.io:1234/subpath/api/123/envelope/?sentry_key=abc&sentry_version=7&sentry_client=sentry.javascript.browser%2F12.31.12',
4037
],
4138
])(
4239
'%s',
4340
(
4441
_testName: string,
4542
dsnComponents: DsnComponents,
46-
tunnelOrOptions: string | ClientOptions | undefined,
43+
tunnel: string | undefined,
44+
sdkInfo: SdkInfo | undefined,
4745
expected: string,
4846
) => {
49-
expect(getEnvelopeEndpointWithUrlEncodedAuth(dsnComponents, tunnelOrOptions)).toBe(expected);
47+
expect(getEnvelopeEndpointWithUrlEncodedAuth(dsnComponents, tunnel, sdkInfo)).toBe(expected);
5048
},
5149
);
5250
});

packages/node-experimental/src/integrations/anr/common.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ export interface WorkerStartData extends AnrIntegrationOptions {
3737
debug: boolean;
3838
sdkMetadata: SdkMetadata;
3939
dsn: DsnComponents;
40+
tunnel: string | undefined;
4041
release: string | undefined;
4142
environment: string;
4243
dist: string | undefined;

packages/node-experimental/src/integrations/anr/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ async function _startWorker(client: NodeClient, _options: Partial<AnrIntegration
7373
const options: WorkerStartData = {
7474
debug: logger.isEnabled(),
7575
dsn,
76+
tunnel: initOptions.tunnel,
7677
environment: initOptions.environment || 'production',
7778
release: initOptions.release,
7879
dist: initOptions.dist,

packages/node-experimental/src/integrations/anr/worker.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ function log(msg: string): void {
3333
}
3434
}
3535

36-
const url = getEnvelopeEndpointWithUrlEncodedAuth(options.dsn);
36+
const url = getEnvelopeEndpointWithUrlEncodedAuth(options.dsn, options.tunnel, options.sdkMetadata.sdk);
3737
const transport = makeNodeTransport({
3838
url,
3939
recordDroppedEvent: () => {
@@ -47,7 +47,7 @@ async function sendAbnormalSession(): Promise<void> {
4747
log('Sending abnormal session');
4848
updateSession(session, { status: 'abnormal', abnormal_mechanism: 'anr_foreground' });
4949

50-
const envelope = createSessionEnvelope(session, options.dsn, options.sdkMetadata);
50+
const envelope = createSessionEnvelope(session, options.dsn, options.sdkMetadata, options.tunnel);
5151
// Log the envelope so to aid in testing
5252
log(JSON.stringify(envelope));
5353

@@ -119,15 +119,15 @@ async function sendAnrEvent(frames?: StackFrame[], traceContext?: TraceContext):
119119
tags: options.staticTags,
120120
};
121121

122-
const envelope = createEventEnvelope(event, options.dsn, options.sdkMetadata);
123-
// Log the envelope so to aid in testing
122+
const envelope = createEventEnvelope(event, options.dsn, options.sdkMetadata, options.tunnel);
123+
// Log the envelope to aid in testing
124124
log(JSON.stringify(envelope));
125125

126126
await transport.send(envelope);
127127
await transport.flush(2000);
128128

129-
// Delay for 5 seconds so that stdio can flush in the main event loop ever restarts.
130-
// This is mainly for the benefit of logging/debugging issues.
129+
// Delay for 5 seconds so that stdio can flush if the main event loop ever restarts.
130+
// This is mainly for the benefit of logging or debugging.
131131
setTimeout(() => {
132132
process.exit(0);
133133
}, 5_000);

0 commit comments

Comments
 (0)