Skip to content

Commit ea20c21

Browse files
author
Luca Forstner
authored
test(e2e): Fix event buffering (#13233)
1 parent 420aaf8 commit ea20c21

File tree

4 files changed

+42
-87
lines changed

4 files changed

+42
-87
lines changed

dev-packages/e2e-tests/Dockerfile.publish-packages

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ ARG NODE_VERSION=18.18.0
33
FROM node:${NODE_VERSION}
44

55
WORKDIR /sentry-javascript/dev-packages/e2e-tests
6-
CMD [ "yarn", "ts-node", "publish-packages.ts" ]
6+
CMD [ "yarn", "ts-node", "publish-packages.ts", "--transpile-only" ]

dev-packages/e2e-tests/publish-packages.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,22 @@ const packageTarballPaths = glob.sync('packages/*/sentry-*.tgz', {
1313
// Publish built packages to the fake registry
1414
packageTarballPaths.forEach(tarballPath => {
1515
// `--userconfig` flag needs to be before `publish`
16-
childProcess.execSync(`npm --userconfig ${__dirname}/test-registry.npmrc publish ${tarballPath}`, {
17-
cwd: repositoryRoot, // Can't use __dirname here because npm would try to publish `@sentry-internal/e2e-tests`
18-
encoding: 'utf8',
19-
stdio: 'inherit',
20-
});
16+
childProcess.exec(
17+
`npm --userconfig ${__dirname}/test-registry.npmrc publish ${tarballPath}`,
18+
{
19+
cwd: repositoryRoot, // Can't use __dirname here because npm would try to publish `@sentry-internal/e2e-tests`
20+
encoding: 'utf8',
21+
},
22+
(err, stdout, stderr) => {
23+
// eslint-disable-next-line no-console
24+
console.log(stdout);
25+
// eslint-disable-next-line no-console
26+
console.log(stderr);
27+
if (err) {
28+
// eslint-disable-next-line no-console
29+
console.error(err);
30+
process.exit(1);
31+
}
32+
},
33+
);
2134
});

dev-packages/e2e-tests/test-applications/aws-serverless-esm/start-event-proxy.mjs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,4 @@ import { startEventProxyServer } from '@sentry-internal/test-utils';
33
startEventProxyServer({
44
port: 3031,
55
proxyServerName: 'aws-serverless-esm',
6-
forwardToSentry: false,
76
});

dev-packages/test-utils/src/event-proxy-server.ts

Lines changed: 23 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
/* eslint-disable max-lines */
2-
32
import * as fs from 'fs';
43
import * as http from 'http';
54
import type { AddressInfo } from 'net';
@@ -18,11 +17,6 @@ interface EventProxyServerOptions {
1817
port: number;
1918
/** The name for the proxy server used for referencing it with listener functions */
2019
proxyServerName: string;
21-
/**
22-
* Whether or not to forward the event to sentry. @default `false`
23-
* This is helpful when you can't register a tunnel in the SDK setup (e.g. lambda layer without Sentry.init call)
24-
*/
25-
forwardToSentry?: boolean;
2620
}
2721

2822
interface SentryRequestCallbackData {
@@ -36,12 +30,16 @@ interface EventCallbackListener {
3630
(data: string): void;
3731
}
3832

33+
type SentryResponseStatusCode = number;
34+
type SentryResponseBody = string;
35+
type SentryResponseHeaders = Record<string, string> | undefined;
36+
3937
type OnRequest = (
4038
eventCallbackListeners: Set<EventCallbackListener>,
4139
proxyRequest: http.IncomingMessage,
4240
proxyRequestBody: string,
4341
eventBuffer: BufferedEvent[],
44-
) => Promise<[number, string, Record<string, string> | undefined]>;
42+
) => Promise<[SentryResponseStatusCode, SentryResponseBody, SentryResponseHeaders]>;
4543

4644
interface BufferedEvent {
4745
timestamp: number;
@@ -170,83 +168,28 @@ export async function startProxyServer(
170168
*/
171169
export async function startEventProxyServer(options: EventProxyServerOptions): Promise<void> {
172170
await startProxyServer(options, async (eventCallbackListeners, proxyRequest, proxyRequestBody, eventBuffer) => {
173-
const envelopeHeader: EnvelopeItem[0] = JSON.parse(proxyRequestBody.split('\n')[0] as string);
171+
const data: SentryRequestCallbackData = {
172+
envelope: parseEnvelope(proxyRequestBody),
173+
rawProxyRequestBody: proxyRequestBody,
174+
rawSentryResponseBody: '',
175+
sentryResponseStatusCode: 200,
176+
};
174177

175-
const shouldForwardEventToSentry = options.forwardToSentry || false;
178+
const dataString = Buffer.from(JSON.stringify(data)).toString('base64');
176179

177-
if (!envelopeHeader.dsn && shouldForwardEventToSentry) {
178-
// eslint-disable-next-line no-console
179-
console.log(
180-
'[event-proxy-server] Warn: No dsn on envelope header. Maybe a client-report was received. Proxy request body:',
181-
proxyRequestBody,
182-
);
183-
184-
return [200, '{}', {}];
185-
}
186-
187-
if (!shouldForwardEventToSentry) {
188-
const data: SentryRequestCallbackData = {
189-
envelope: parseEnvelope(proxyRequestBody),
190-
rawProxyRequestBody: proxyRequestBody,
191-
rawSentryResponseBody: '',
192-
sentryResponseStatusCode: 200,
193-
};
194-
eventCallbackListeners.forEach(listener => {
195-
listener(Buffer.from(JSON.stringify(data)).toString('base64'));
196-
});
197-
198-
return [
199-
200,
200-
'{}',
201-
{
202-
'Access-Control-Allow-Origin': '*',
203-
},
204-
];
205-
}
206-
207-
const { origin, pathname, host } = new URL(envelopeHeader.dsn as string);
208-
209-
const projectId = pathname.substring(1);
210-
const sentryIngestUrl = `${origin}/api/${projectId}/envelope/`;
211-
212-
proxyRequest.headers.host = host;
213-
214-
const reqHeaders: Record<string, string> = {};
215-
for (const [key, value] of Object.entries(proxyRequest.headers)) {
216-
reqHeaders[key] = value as string;
217-
}
218-
219-
// Fetch does not like this
220-
delete reqHeaders['transfer-encoding'];
221-
222-
return fetch(sentryIngestUrl, {
223-
body: proxyRequestBody,
224-
headers: reqHeaders,
225-
method: proxyRequest.method,
226-
}).then(async res => {
227-
const rawSentryResponseBody = await res.text();
228-
const data: SentryRequestCallbackData = {
229-
envelope: parseEnvelope(proxyRequestBody),
230-
rawProxyRequestBody: proxyRequestBody,
231-
rawSentryResponseBody,
232-
sentryResponseStatusCode: res.status,
233-
};
234-
235-
const dataString = Buffer.from(JSON.stringify(data)).toString('base64');
236-
237-
eventBuffer.push({ data: dataString, timestamp: getNanosecondTimestamp() });
238-
239-
eventCallbackListeners.forEach(listener => {
240-
listener(dataString);
241-
});
242-
243-
const resHeaders: Record<string, string> = {};
244-
for (const [key, value] of res.headers.entries()) {
245-
resHeaders[key] = value;
246-
}
180+
eventBuffer.push({ data: dataString, timestamp: getNanosecondTimestamp() });
247181

248-
return [res.status, rawSentryResponseBody, resHeaders];
182+
eventCallbackListeners.forEach(listener => {
183+
listener(dataString);
249184
});
185+
186+
return [
187+
200,
188+
'{}',
189+
{
190+
'Access-Control-Allow-Origin': '*',
191+
},
192+
];
250193
});
251194
}
252195

0 commit comments

Comments
 (0)