Skip to content

meta(changelog): Update changelog for 7.65.0 #8878

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
Aug 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
d1e0135
Merge pull request #8812 from getsentry/master
github-actions[bot] Aug 14, 2023
e6e6ebf
fix(nextjs): Check for validity of API route handler signature (#8811)
Aug 14, 2023
448406a
build: Remove build-specific polyfills (#8809)
mydea Aug 14, 2023
5c085ef
feat(core): Introduce `Sentry.startActiveSpan` and `Sentry.startSpan`…
AbhiPrasad Aug 15, 2023
dc653d0
build(deps): bump protobufjs from 6.11.3 to 6.11.4 (#8822)
dependabot[bot] Aug 16, 2023
65df869
fix(sveltekit): Avoid invalidating data on route changes in `wrapServ…
Lms24 Aug 16, 2023
c20e0fb
fix(node): More relevant warning message when tracing extensions are …
timfish Aug 17, 2023
39bf783
build: Fix typo in size limit config (#8825)
mydea Aug 17, 2023
490631e
feat(ci): Cache `node_modules` in flaky test detector (#8787)
billyvg Aug 17, 2023
a6e2642
ref(sveltekit): Remove custom client fetch instrumentation and use de…
Lms24 Aug 17, 2023
e5a3885
fix: Memoize `AsyncLocalStorage` instance (#8831)
Aug 17, 2023
ff26887
test(replay): Fix flakes from `customEvents` (#8827)
billyvg Aug 17, 2023
a985738
fix(sveltekit): Remove invalid return in fetch proxy script (#8835)
Lms24 Aug 17, 2023
4a4df0d
fix(replay): Streamline session creation/refresh (#8813)
mydea Aug 18, 2023
88611c7
test(overhead): Stop loading `api.lorem.space` images (#8833)
billyvg Aug 18, 2023
2d80b4b
build(angular): Fix Nx dependency graph for Angular (#8841)
mydea Aug 18, 2023
81efb87
chore(repo): Fix Package: SvelteKit/Svelte label assignment workflow …
Lms24 Aug 28, 2023
891a44e
fix(tracing): Better guarding for performance observer (#8872)
mydea Aug 28, 2023
478b5e2
fix(nextjs): Fix `requestAsyncStorageShim` path resolution on windows…
Aug 28, 2023
4be150e
deps(sveltekit): Bump `@sentry/vite-plugin` (#8877)
Aug 28, 2023
5afb861
fix(node): Log entire error object in `OnUncaughtException` (#8876)
Lms24 Aug 28, 2023
341bc4c
ref(tracing-internal): Deprecate `tracePropagationTargets` in `Browse…
Lms24 Aug 28, 2023
31979c6
meta(changelog): Update changelog for 7.65.0
Aug 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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