Skip to content

Commit

Permalink
Merge pull request #8187 from getsentry/prepare-release/7.53.0
Browse files Browse the repository at this point in the history
meta: Update Changelog for 7.53.0
  • Loading branch information
Lms24 committed May 23, 2023
2 parents ff4b1a8 + 573514a commit 48e9f7e
Show file tree
Hide file tree
Showing 50 changed files with 1,533 additions and 399 deletions.
38 changes: 1 addition & 37 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -253,43 +253,6 @@ jobs:
# `job_build` can't see `job_install_deps` and what it returned)
dependency_cache_key: ${{ needs.job_install_deps.outputs.dependency_cache_key }}

job_pack_aws_lambda_layer:
name: Pack and Upload AWS Lambda Layer
needs: [job_get_metadata, job_build]
# only upload the zipped layer file if we're about to release
if: startsWith(github.ref, 'refs/heads/release/')
runs-on: ubuntu-20.04
steps:
- name: Check out current commit (${{ needs.job_get_metadata.outputs.commit_label }})
uses: actions/checkout@v3
with:
ref: ${{ env.HEAD_COMMIT }}
- name: Set up Node
uses: actions/setup-node@v3
with:
node-version-file: 'package.json'
- name: Restore caches
uses: ./.github/actions/restore-cache
env:
DEPENDENCY_CACHE_KEY: ${{ needs.job_build.outputs.dependency_cache_key }}

- name: Get SDK version
# `jq` reads JSON files, and `tee` pipes its input to the given location and to stdout. (Adding `-a` is the
# equivalent of using >> rather than >.)
run: |
export SDK_VERSION=$(cat packages/core/package.json | jq --raw-output '.version')
echo "SDK_VERSION=$SDK_VERSION" | tee -a $GITHUB_ENV
- name: Move dist-serverless to root directory (requirement for zipping action)
run: |
mv ./packages/serverless/build/aws/dist-serverless .
- name: Create and upload final zip file
uses: getsentry/action-build-aws-lambda-extension@v1
with:
artifact_name: ${{ env.HEAD_COMMIT }}
zip_file_name: sentry-node-serverless-${{ env.SDK_VERSION }}.zip
build_cache_paths: ${{ env.CACHED_BUILD_PATHS }}
build_cache_key: ${{ env.BUILD_CACHE_KEY }}

job_size_check:
name: Size Check
needs: [job_get_metadata, job_build]
Expand Down Expand Up @@ -399,6 +362,7 @@ jobs:
${{ github.workspace }}/packages/integrations/build/bundles/**
${{ github.workspace }}/packages/replay/build/bundles/**
${{ github.workspace }}/packages/**/*.tgz
${{ github.workspace }}/packages/serverless/build/aws/dist-serverless/*.zip
job_browser_unit_tests:
name: Browser Unit Tests
Expand Down
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,27 @@

## Unreleased


- "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott

## 7.53.0

- feat(replay): Add `beforeAddRecordingEvent` Replay option (#8124)
- feat(replay): Do not capture replays < 5 seconds (#7949)
- fix(nextjs): Guard for non-absolute paths when injecting sentry config (#8151)
- fix(nextjs): Import path issue on Windows (#8142)
- fix(nextjs): Make `withSentryConfig` isomorphic (#8166)
- fix(node): Add debug logging for node checkin (#8131)
- fix(node): Add LRU map for tracePropagationTargets calculation (#8130)
- fix(node): Remove new URL usage in Undici integration (#8147)
- fix(replay): Show the correct Replay config option name `maskFn`
- fix(sveltekit): Avoid double-wrapping load functions (#8094)
- fix(tracing): Change where content-length gets added (#8139)
- fix(tracing): Use integer for content length (#8152)
- fix(utils): Fail silently if the provided Dsn is invalid (#8121)
- ref(node): Cache undici trace propagation decisions (#8136)
- ref(serverless): Remove relay extension from AWS Layer (#8080)

## 7.52.1

- feat(replay): Capture slow clicks (experimental) (#8052)
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ export function getReportDialogEndpoint(
},
): string {
const dsn = makeDsn(dsnLike);
if (!dsn) {
return '';
}

const endpoint = `${getBaseApiEndpoint(dsn)}embed/error-page/`;

let encodedOptions = `dsn=${dsnToString(dsn)}`;
Expand Down
8 changes: 6 additions & 2 deletions packages/core/src/baseclient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,20 @@ export abstract class BaseClient<O extends ClientOptions> implements Client<O> {
*/
protected constructor(options: O) {
this._options = options;

if (options.dsn) {
this._dsn = makeDsn(options.dsn);
} else {
__DEBUG_BUILD__ && logger.warn('No DSN provided, client will not do anything.');
}

if (this._dsn) {
const url = getEnvelopeEndpointWithUrlEncodedAuth(this._dsn, options);
this._transport = options.transport({
recordDroppedEvent: this.recordDroppedEvent.bind(this),
...options.transportOptions,
url,
});
} else {
__DEBUG_BUILD__ && logger.warn('No DSN provided, client will not do anything.');
}
}

Expand Down
12 changes: 9 additions & 3 deletions packages/core/src/transports/multiplexed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,13 @@ export function makeMultiplexedTransport<TO extends BaseTransportOptions>(
const fallbackTransport = createTransport(options);
const otherTransports: Record<string, Transport> = {};

function getTransport(dsn: string): Transport {
function getTransport(dsn: string): Transport | undefined {
if (!otherTransports[dsn]) {
const url = getEnvelopeEndpointWithUrlEncodedAuth(dsnFromString(dsn));
const validatedDsn = dsnFromString(dsn);
if (!validatedDsn) {
return undefined;
}
const url = getEnvelopeEndpointWithUrlEncodedAuth(validatedDsn);
otherTransports[dsn] = createTransport({ ...options, url });
}

Expand All @@ -66,7 +70,9 @@ export function makeMultiplexedTransport<TO extends BaseTransportOptions>(
return eventFromEnvelope(envelope, eventTypes);
}

const transports = matcher({ envelope, getEvent }).map(dsn => getTransport(dsn));
const transports = matcher({ envelope, getEvent })
.map(dsn => getTransport(dsn))
.filter((t): t is Transport => !!t);

// If we have no transports to send to, use the fallback transport
if (transports.length === 0) {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/test/lib/api.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const dsnPublic = 'https://abc@sentry.io:1234/subpath/123';
const tunnel = 'https://hello.com/world';
const _metadata = { sdk: { name: 'sentry.javascript.browser', version: '12.31.12' } } as ClientOptions['_metadata'];

const dsnPublicComponents = makeDsn(dsnPublic);
const dsnPublicComponents = makeDsn(dsnPublic)!;

describe('API', () => {
describe('getEnvelopeEndpointWithUrlEncodedAuth', () => {
Expand Down
12 changes: 6 additions & 6 deletions packages/core/test/lib/base.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,19 +70,19 @@ describe('BaseClient', () => {
});

test('allows missing Dsn', () => {
expect.assertions(1);

const options = getDefaultTestClientOptions();
const client = new TestClient(options);

expect(client.getDsn()).toBeUndefined();
expect(client.getTransport()).toBeUndefined();
});

test('throws with invalid Dsn', () => {
expect.assertions(1);

test('handles being passed an invalid Dsn', () => {
const options = getDefaultTestClientOptions({ dsn: 'abc' });
expect(() => new TestClient(options)).toThrow(SentryError);
const client = new TestClient(options);

expect(client.getDsn()).toBeUndefined();
expect(client.getTransport()).toBeUndefined();
});
});

Expand Down
18 changes: 16 additions & 2 deletions packages/core/test/lib/transports/multiplexed.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ import { TextEncoder } from 'util';
import { createTransport, getEnvelopeEndpointWithUrlEncodedAuth, makeMultiplexedTransport } from '../../../src';

const DSN1 = 'https://1234@5678.ingest.sentry.io/4321';
const DSN1_URL = getEnvelopeEndpointWithUrlEncodedAuth(dsnFromString(DSN1));
const DSN1_URL = getEnvelopeEndpointWithUrlEncodedAuth(dsnFromString(DSN1)!);

const DSN2 = 'https://5678@1234.ingest.sentry.io/8765';
const DSN2_URL = getEnvelopeEndpointWithUrlEncodedAuth(dsnFromString(DSN2));
const DSN2_URL = getEnvelopeEndpointWithUrlEncodedAuth(dsnFromString(DSN2)!);

const ERROR_EVENT = { event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2' };
const ERROR_ENVELOPE = createEnvelope<EventEnvelope>({ event_id: 'aa3ff046696b4bc6b609ce6d28fde9e2', sent_at: '123' }, [
Expand Down Expand Up @@ -83,6 +83,20 @@ describe('makeMultiplexedTransport', () => {
await transport.send(ERROR_ENVELOPE);
});

it('Falls back to options DSN when a matched DSN is invalid', async () => {
expect.assertions(1);

const makeTransport = makeMultiplexedTransport(
createTestTransport(url => {
expect(url).toBe(DSN1_URL);
}),
() => ['invalidDsn'],
);

const transport = makeTransport({ url: DSN1_URL, ...transportOptions });
await transport.send(ERROR_ENVELOPE);
});

it('DSN can be overridden via match callback', async () => {
expect.assertions(1);

Expand Down
2 changes: 1 addition & 1 deletion packages/core/test/lib/transports/offline.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const REPLAY_EVENT: ReplayEvent = {
replay_type: 'buffer',
};

const DSN = dsnFromString('https://public@dsn.ingest.sentry.io/1337');
const DSN = dsnFromString('https://public@dsn.ingest.sentry.io/1337')!;

const DATA = 'nothing';

Expand Down
7 changes: 7 additions & 0 deletions packages/nextjs/src/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@ function addClientIntegrations(options: BrowserOptions): void {
options.integrations = integrations;
}

/**
* Just a passthrough in case this is imported from the client.
*/
export function withSentryConfig<T>(exportedUserNextConfig: T): T {
return exportedUserNextConfig;
}

export {
// eslint-disable-next-line deprecation/deprecation
withSentryServerSideGetInitialProps,
Expand Down
3 changes: 3 additions & 0 deletions packages/nextjs/src/client/tunnelRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ export function applyTunnelRouteOption(options: BrowserOptions): void {
const tunnelRouteOption = globalWithInjectedValues.__sentryRewritesTunnelPath__;
if (tunnelRouteOption && options.dsn) {
const dsnComponents = dsnFromString(options.dsn);
if (!dsnComponents) {
return;
}
const sentrySaasDsnMatch = dsnComponents.host.match(/^o(\d+)\.ingest\.sentry\.io$/);
if (sentrySaasDsnMatch) {
const orgId = sentrySaasDsnMatch[1];
Expand Down
9 changes: 7 additions & 2 deletions packages/nextjs/src/config/loaders/wrappingLoader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,13 @@ export default function wrappingLoader(
templateCode = templateCode.replace(/__COMPONENT_TYPE__/g, 'Unknown');
}

if (sentryConfigFilePath) {
templateCode = `import "${sentryConfigFilePath}";`.concat(templateCode);
// We check whether `this.resourcePath` is absolute because there is no contract by webpack that says it is absolute,
// however we can only create relative paths to the sentry config from absolute paths.Examples where this could possibly be non - absolute are virtual modules.
if (sentryConfigFilePath && path.isAbsolute(this.resourcePath)) {
const sentryConfigImportPath = path
.relative(path.dirname(this.resourcePath), sentryConfigFilePath) // Absolute paths do not work with Windows: https://github.com/getsentry/sentry-javascript/issues/8133
.replace(/\\/g, '/');
templateCode = `import "${sentryConfigImportPath}";\n`.concat(templateCode);
}
} else if (wrappingTargetKind === 'middleware') {
templateCode = middlewareWrapperTemplateCode;
Expand Down
7 changes: 7 additions & 0 deletions packages/nextjs/src/edge/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,13 @@ export function lastEventId(): string | undefined {
return getCurrentHub().lastEventId();
}

/**
* Just a passthrough in case this is imported from the client.
*/
export function withSentryConfig<T>(exportedUserNextConfig: T): T {
return exportedUserNextConfig;
}

export { flush } from './utils/flush';

export * from '@sentry/core';
Expand Down
2 changes: 2 additions & 0 deletions packages/nextjs/src/index.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ export declare const withErrorBoundary: typeof clientSdk.withErrorBoundary;
export declare const Span: typeof edgeSdk.Span;
export declare const Transaction: typeof edgeSdk.Transaction;

export { withSentryConfig } from './config';

/**
* @deprecated Use `wrapApiHandlerWithSentry` instead
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,12 @@ test('should correctly instrument `fetch` for performance tracing', async ({ pag
expect(transaction[0].spans).toEqual(
expect.arrayContaining([
expect.objectContaining({
data: { 'http.method': 'GET', url: 'http://example.com', type: 'fetch' },
data: {
'http.method': 'GET',
url: 'http://example.com',
type: 'fetch',
'http.response_content_length': expect.any(Number),
},
description: 'GET http://example.com',
op: 'http.client',
parent_span_id: expect.any(String),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import next from 'next';
// Type not exported from NextJS
// @ts-ignore
export const createNextServer = async config => {
const app = next(config);
const app = next({ ...config, customServer: false }); // customServer: false because: https://github.com/vercel/next.js/pull/49805#issuecomment-1557321794
const handle = app.getRequestHandler();
await app.prepare();

Expand Down
19 changes: 15 additions & 4 deletions packages/nextjs/test/utils/tunnelRoute.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ beforeEach(() => {
});

describe('applyTunnelRouteOption()', () => {
it('should correctly apply `tunnelRoute` option when conditions are met', () => {
it('Correctly applies `tunnelRoute` option when conditions are met', () => {
globalWithInjectedValues.__sentryRewritesTunnelPath__ = '/my-error-monitoring-route';
const options: any = {
dsn: 'https://11111111111111111111111111111111@o2222222.ingest.sentry.io/3333333',
Expand All @@ -22,7 +22,7 @@ describe('applyTunnelRouteOption()', () => {
expect(options.tunnel).toBe('/my-error-monitoring-route?o=2222222&p=3333333');
});

it('should not apply `tunnelRoute` when DSN is missing', () => {
it("Doesn't apply `tunnelRoute` when DSN is missing", () => {
globalWithInjectedValues.__sentryRewritesTunnelPath__ = '/my-error-monitoring-route';
const options: any = {
// no dsn
Expand All @@ -33,7 +33,18 @@ describe('applyTunnelRouteOption()', () => {
expect(options.tunnel).toBeUndefined();
});

it("should not apply `tunnelRoute` option when `tunnelRoute` option wasn't injected", () => {
it("Doesn't apply `tunnelRoute` when DSN is invalid", () => {
globalWithInjectedValues.__sentryRewritesTunnelPath__ = '/my-error-monitoring-route';
const options: any = {
dsn: 'invalidDsn',
} as BrowserOptions;

applyTunnelRouteOption(options);

expect(options.tunnel).toBeUndefined();
});

it("Doesn't apply `tunnelRoute` option when `tunnelRoute` option wasn't injected", () => {
const options: any = {
dsn: 'https://11111111111111111111111111111111@o2222222.ingest.sentry.io/3333333',
} as BrowserOptions;
Expand All @@ -43,7 +54,7 @@ describe('applyTunnelRouteOption()', () => {
expect(options.tunnel).toBeUndefined();
});

it('should not apply `tunnelRoute` option when DSN is not a SaaS DSN', () => {
it("Doesn't `tunnelRoute` option when DSN is not a SaaS DSN", () => {
globalWithInjectedValues.__sentryRewritesTunnelPath__ = '/my-error-monitoring-route';
const options: any = {
dsn: 'https://11111111111111111111111111111111@example.com/3333333',
Expand Down
2 changes: 2 additions & 0 deletions packages/node/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,8 @@ export class NodeClient extends BaseClient<NodeClientOptions> {
}

const envelope = createCheckInEnvelope(serializedCheckIn, this.getSdkMetadata(), tunnel, this.getDsn());

__DEBUG_BUILD__ && logger.info('Sending checkin:', checkIn.monitorSlug, checkIn.status);
void this._sendEnvelope(envelope);
return id;
}
Expand Down
13 changes: 7 additions & 6 deletions packages/node/src/integrations/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ function _createWrappedRequestMethodFactory(
): WrappedRequestMethodFactory {
// We're caching results so we don't have to recompute regexp every time we create a request.
const createSpanUrlMap = new LRUMap<string, boolean>(100);
const headersUrlMap: Record<string, boolean> = {};
const headersUrlMap = new LRUMap<string, boolean>(100);

const shouldCreateSpan = (url: string): boolean => {
if (tracingOptions?.shouldCreateSpanForRequest === undefined) {
Expand All @@ -160,13 +160,14 @@ function _createWrappedRequestMethodFactory(
return true;
}

if (headersUrlMap[url]) {
return headersUrlMap[url];
const cachedDecision = headersUrlMap.get(url);
if (cachedDecision !== undefined) {
return cachedDecision;
}

headersUrlMap[url] = stringMatchesSomePattern(url, tracingOptions.tracePropagationTargets);

return headersUrlMap[url];
const decision = stringMatchesSomePattern(url, tracingOptions.tracePropagationTargets);
headersUrlMap.set(url, decision);
return decision;
};

return function wrappedRequestMethodFactory(originalRequestMethod: OriginalRequestMethod): WrappedRequestMethod {
Expand Down

0 comments on commit 48e9f7e

Please sign in to comment.