Skip to content

Commit

Permalink
Merge pull request #8878 from getsentry/prepare-release/7.65.0
Browse files Browse the repository at this point in the history
  • Loading branch information
lforst authored Aug 28, 2023
2 parents b30936c + 31979c6 commit 0d30afc
Show file tree
Hide file tree
Showing 77 changed files with 1,413 additions and 1,878 deletions.
1 change: 1 addition & 0 deletions .github/workflows/flaky-test-detector.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ jobs:
uses: actions/setup-node@v3
with:
node-version-file: 'package.json'
cache: 'yarn'
- name: Install dependencies
run: yarn install --ignore-engines --frozen-lockfile

Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/issue-package-label.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,12 @@ jobs:
"@sentry.serverless": {
"label": "Package: Serverless"
},
"@sentry.svelte": {
"label": "Package: svelte"
},
"@sentry.sveltekit": {
"label": "Package: SvelteKit"
},
"@sentry.svelte": {
"label": "Package: svelte"
},
"@sentry.vue": {
"label": "Package: vue"
},
Expand Down
2 changes: 1 addition & 1 deletion .size-limit.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ module.exports = [
{
name: '@sentry/react (incl. Tracing, Replay) - Webpack (gzipped)',
path: 'packages/react/build/esm/index.js',
import: '{ init, BrowserTYracing, Replay }',
import: '{ init, BrowserTracing, Replay }',
gzip: true,
limit: '80 KB',
},
Expand Down
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@

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

## 7.65.0

- build: Remove build-specific polyfills (#8809)
- build(deps): bump protobufjs from 6.11.3 to 6.11.4 (#8822)
- deps(sveltekit): Bump `@sentry/vite-plugin` (#8877)
- feat(core): Introduce `Sentry.startActiveSpan` and `Sentry.startSpan` (#8803)
- fix: Memoize `AsyncLocalStorage` instance (#8831)
- fix(nextjs): Check for validity of API route handler signature (#8811)
- fix(nextjs): Fix `requestAsyncStorageShim` path resolution on windows (#8875)
- fix(node): Log entire error object in `OnUncaughtException` (#8876)
- fix(node): More relevant warning message when tracing extensions are missing (#8820)
- fix(replay): Streamline session creation/refresh (#8813)
- fix(sveltekit): Avoid invalidating data on route changes in `wrapServerLoadWithSentry` (#8801)
- fix(tracing): Better guarding for performance observer (#8872)
- ref(sveltekit): Remove custom client fetch instrumentation and use default instrumentation (#8802)
- ref(tracing-internal): Deprecate `tracePropagationTargets` in `BrowserTracing` (#8874)

## 7.64.0

- feat(core): Add setMeasurement export (#8791)
Expand Down
13 changes: 12 additions & 1 deletion packages/angular-ivy/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,16 @@
"volta": {
"extends": "../../package.json"
},
"sideEffects": false
"sideEffects": false,
"nx": {
"targets": {
"build:transpile": {
"dependsOn": [
"^build:transpile",
"^build:transpile:uncached",
"^build:types"
]
}
}
}
}
13 changes: 12 additions & 1 deletion packages/angular/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,5 +65,16 @@
"volta": {
"extends": "../../package.json"
},
"sideEffects": false
"sideEffects": false,
"nx": {
"targets": {
"build:transpile": {
"dependsOn": [
"^build:transpile",
"^build:transpile:uncached",
"^build:types"
]
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import * as Sentry from '@sentry/browser';

window.Sentry = Sentry;
window.Replay = new Sentry.Replay({
flushMinDelay: 200,
flushMaxDelay: 200,
minReplayDuration: 0,
});

Sentry.init({
dsn: 'https://[email protected]/1337',
sampleRate: 1,
replaysSessionSampleRate: 0.0,
replaysOnErrorSampleRate: 1.0,

integrations: [window.Replay],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<button onclick="console.log('Test log 1')" id="button1">Click me</button>
<button onclick="Sentry.captureException('test error')" id="buttonError">Click me</button>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { expect } from '@playwright/test';

import { sentryTest } from '../../../utils/fixtures';
import {
getReplaySnapshot,
shouldSkipReplayTest,
waitForReplayRequest,
waitForReplayRunning,
} from '../../../utils/replayHelpers';

sentryTest('continues buffer session in session mode after error & reload', async ({ getLocalTestPath, page }) => {
if (shouldSkipReplayTest()) {
sentryTest.skip();
}

const reqPromise1 = waitForReplayRequest(page, 0);

await page.route('https://dsn.ingest.sentry.io/**/*', route => {
return route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ id: 'test-id' }),
});
});

const url = await getLocalTestPath({ testDir: __dirname });

await page.goto(url);

// buffer session captures an error & switches to session mode
await page.click('#buttonError');
await new Promise(resolve => setTimeout(resolve, 300));
await reqPromise1;

await waitForReplayRunning(page);
const replay1 = await getReplaySnapshot(page);

expect(replay1.recordingMode).toEqual('session');
expect(replay1.session?.sampled).toEqual('buffer');
expect(replay1.session?.segmentId).toBeGreaterThan(0);

// Reload to ensure the session is correctly recovered from sessionStorage
await page.reload();

await waitForReplayRunning(page);
const replay2 = await getReplaySnapshot(page);

expect(replay2.recordingMode).toEqual('session');
expect(replay2.session?.sampled).toEqual('buffer');
expect(replay2.session?.segmentId).toBeGreaterThan(0);
});
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ sentryTest(

const reqPromise0 = waitForReplayRequest(page, 0);
const reqPromise1 = waitForReplayRequest(page, 1);
const reqPromise2 = waitForReplayRequest(page, 2);
const reqPromise3 = waitForReplayRequest(page, 3);

await page.route('https://dsn.ingest.sentry.io/**/*', route => {
return route.fulfill({
Expand All @@ -103,8 +105,6 @@ sentryTest(
await reqPromise0;

await page.click('#error');
await page.click('#img');
await page.click('.sentry-unmask');
await forceFlushReplay();
const req1 = await reqPromise1;
const content1 = getReplayRecordingContent(req1);
Expand All @@ -131,7 +131,11 @@ sentryTest(
]),
);

expect(content1.breadcrumbs).toEqual(
await page.click('#img');
await forceFlushReplay();
const req2 = await reqPromise2;
const content2 = getReplayRecordingContent(req2);
expect(content2.breadcrumbs).toEqual(
expect.arrayContaining([
{
...expectedClickBreadcrumb,
Expand All @@ -151,7 +155,11 @@ sentryTest(
]),
);

expect(content1.breadcrumbs).toEqual(
await page.click('.sentry-unmask');
await forceFlushReplay();
const req3 = await reqPromise3;
const content3 = getReplayRecordingContent(req3);
expect(content3.breadcrumbs).toEqual(
expect.arrayContaining([
{
...expectedClickBreadcrumb,
Expand Down
12 changes: 10 additions & 2 deletions packages/core/src/hub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -374,11 +374,19 @@ export class Hub implements HubInterface {
const result = this._callExtensionMethod<Transaction>('startTransaction', context, customSamplingContext);

if (__DEBUG_BUILD__ && !result) {
// eslint-disable-next-line no-console
console.warn(`Tracing extension 'startTransaction' has not been added. Call 'addTracingExtensions' before calling 'init':
const client = this.getClient();
if (!client) {
// eslint-disable-next-line no-console
console.warn(
"Tracing extension 'startTransaction' is missing. You should 'init' the SDK before calling 'startTransaction'",
);
} else {
// eslint-disable-next-line no-console
console.warn(`Tracing extension 'startTransaction' has not been added. Call 'addTracingExtensions' before calling 'init':
Sentry.addTracingExtensions();
Sentry.init({...});
`);
}
}

return result;
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/tracing/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@ export { extractTraceparentData, getActiveTransaction } from './utils';
// eslint-disable-next-line deprecation/deprecation
export { SpanStatus } from './spanstatus';
export type { SpanStatusType } from './span';
export { trace } from './trace';
export { trace, getActiveSpan, startActiveSpan, startSpan } from './trace';
export { getDynamicSamplingContextFromClient } from './dynamicSamplingContext';
export { setMeasurement } from './measurement';
101 changes: 99 additions & 2 deletions packages/core/src/tracing/trace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ export function trace<T>(

const parentSpan = scope.getSpan();

function getActiveSpan(): Span | undefined {
function startActiveSpan(): Span | undefined {
if (!hasTracingEnabled()) {
return undefined;
}
return parentSpan ? parentSpan.startChild(ctx) : hub.startTransaction(ctx);
}

const activeSpan = getActiveSpan();
const activeSpan = startActiveSpan();
scope.setSpan(activeSpan);

function finishAndSetSpan(): void {
Expand Down Expand Up @@ -76,3 +76,100 @@ export function trace<T>(

return maybePromiseResult;
}

/**
* Wraps a function with a transaction/span and finishes the span after the function is done.
* The created span is the active span and will be used as parent by other spans created inside the function
* and can be accessed via `Sentry.getSpan()`, as long as the function is executed while the scope is active.
*
* If you want to create a span that is not set as active, use {@link startSpan}.
*
* Note that if you have not enabled tracing extensions via `addTracingExtensions`
* or you didn't set `tracesSampleRate`, this function will not generate spans
* and the `span` returned from the callback will be undefined.
*/
export function startActiveSpan<T>(context: TransactionContext, callback: (span: Span | undefined) => T): T {
const ctx = { ...context };
// If a name is set and a description is not, set the description to the name.
if (ctx.name !== undefined && ctx.description === undefined) {
ctx.description = ctx.name;
}

const hub = getCurrentHub();
const scope = hub.getScope();

const parentSpan = scope.getSpan();

function startActiveSpan(): Span | undefined {
if (!hasTracingEnabled()) {
return undefined;
}
return parentSpan ? parentSpan.startChild(ctx) : hub.startTransaction(ctx);
}

const activeSpan = startActiveSpan();
scope.setSpan(activeSpan);

function finishAndSetSpan(): void {
activeSpan && activeSpan.finish();
hub.getScope().setSpan(parentSpan);
}

let maybePromiseResult: T;
try {
maybePromiseResult = callback(activeSpan);
} catch (e) {
activeSpan && activeSpan.setStatus('internal_error');
finishAndSetSpan();
throw e;
}

if (isThenable(maybePromiseResult)) {
Promise.resolve(maybePromiseResult).then(
() => {
finishAndSetSpan();
},
() => {
activeSpan && activeSpan.setStatus('internal_error');
finishAndSetSpan();
},
);
} else {
finishAndSetSpan();
}

return maybePromiseResult;
}

/**
* Creates a span. This span is not set as active, so will not get automatic instrumentation spans
* as children or be able to be accessed via `Sentry.getSpan()`.
*
* If you want to create a span that is set as active, use {@link startActiveSpan}.
*
* Note that if you have not enabled tracing extensions via `addTracingExtensions`
* or you didn't set `tracesSampleRate` or `tracesSampler`, this function will not generate spans
* and the `span` returned from the callback will be undefined.
*/
export function startSpan(context: TransactionContext): Span | undefined {
if (!hasTracingEnabled()) {
return undefined;
}

const ctx = { ...context };
// If a name is set and a description is not, set the description to the name.
if (ctx.name !== undefined && ctx.description === undefined) {
ctx.description = ctx.name;
}

const hub = getCurrentHub();
const parentSpan = getActiveSpan();
return parentSpan ? parentSpan.startChild(ctx) : hub.startTransaction(ctx);
}

/**
* Returns the currently active span.
*/
export function getActiveSpan(): Span | undefined {
return getCurrentHub().getScope().getSpan();
}
Loading

0 comments on commit 0d30afc

Please sign in to comment.