Skip to content

Commit

Permalink
Merge pull request #15400 from getsentry/prepare-release/9.1.0
Browse files Browse the repository at this point in the history
meta(changelog): Update changelog for 9.1.0
  • Loading branch information
andreiborza authored Feb 13, 2025
2 parents 6894f8a + 973f241 commit 1a21bdf
Show file tree
Hide file tree
Showing 98 changed files with 3,148 additions and 761 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ env:
nx-Linux-${{ github.ref }}
nx-Linux
# https://bsky.app/profile/joyeecheung.bsky.social/post/3lhy6o54fo22h
# Apparently some of our CI failures are attributable to a corrupt v8 cache, causing v8 failures with: "Check failed: current == end_slot_index.".
# This option both controls the `v8-compile-cache-lib` and `v8-compile-cache` packages.
DISABLE_V8_COMPILE_CACHE: '1'

jobs:
job_get_metadata:
name: Get Metadata
Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@

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

## 9.1.0

- feat(browser): Add `graphqlClientIntegration` ([#13783](https://github.com/getsentry/sentry-javascript/pull/13783))
- feat(core): Allow for nested trpc context ([#15379](https://github.com/getsentry/sentry-javascript/pull/15379))
- feat(core): Create types and utilities for span links ([#15375](https://github.com/getsentry/sentry-javascript/pull/15375))
- feat(deps): bump @opentelemetry/instrumentation-pg from 0.50.0 to 0.51.0 ([#15273](https://github.com/getsentry/sentry-javascript/pull/15273))
- feat(node): Extract Sentry-specific node-fetch instrumentation ([#15231](https://github.com/getsentry/sentry-javascript/pull/15231))
- feat(vue): Support Pinia v3 ([#15383](https://github.com/getsentry/sentry-javascript/pull/15383))
- fix(sveltekit): Avoid request body double read errors ([#15368](https://github.com/getsentry/sentry-javascript/pull/15368))
- fix(sveltekit): Avoid top-level `vite` import ([#15371](https://github.com/getsentry/sentry-javascript/pull/15371))

Work in this release was contributed by @Zen-cronic and @filips-alpe. Thank you for your contribution!

## 9.0.1

- ref(flags): rename unleash integration param ([#15343](https://github.com/getsentry/sentry-javascript/pull/15343))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const query = `query Test{
people {
name
pet
}
}`;

const requestBody = JSON.stringify({ query });

fetch('http://sentry-test.io/foo', {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: requestBody,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { expect } from '@playwright/test';
import type { Event } from '@sentry/core';

import { sentryTest } from '../../../../utils/fixtures';
import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers';

// Duplicate from subject.js
const query = `query Test{
people {
name
pet
}
}`;
const queryPayload = JSON.stringify({ query });

sentryTest('should update spans for GraphQL fetch requests', async ({ getLocalTestUrl, page }) => {
if (shouldSkipTracingTest()) {
return;
}

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

await page.route('**/foo', route => {
return route.fulfill({
status: 200,
body: JSON.stringify({
people: [
{ name: 'Amy', pet: 'dog' },
{ name: 'Jay', pet: 'cat' },
],
}),
headers: {
'Content-Type': 'application/json',
},
});
});

const eventData = await getFirstSentryEnvelopeRequest<Event>(page, url);
const requestSpans = eventData.spans?.filter(({ op }) => op === 'http.client');

expect(requestSpans).toHaveLength(1);

expect(requestSpans![0]).toMatchObject({
description: 'POST http://sentry-test.io/foo (query Test)',
parent_span_id: eventData.contexts?.trace?.span_id,
span_id: expect.any(String),
start_timestamp: expect.any(Number),
timestamp: expect.any(Number),
trace_id: eventData.contexts?.trace?.trace_id,
status: 'ok',
data: expect.objectContaining({
type: 'fetch',
'http.method': 'POST',
'http.url': 'http://sentry-test.io/foo',
url: 'http://sentry-test.io/foo',
'server.address': 'sentry-test.io',
'sentry.op': 'http.client',
'sentry.origin': 'auto.http.browser',
'graphql.document': queryPayload,
}),
});
});

sentryTest('should update breadcrumbs for GraphQL fetch requests', async ({ getLocalTestUrl, page }) => {
if (shouldSkipTracingTest()) {
return;
}

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

await page.route('**/foo', route => {
return route.fulfill({
status: 200,
body: JSON.stringify({
people: [
{ name: 'Amy', pet: 'dog' },
{ name: 'Jay', pet: 'cat' },
],
}),
headers: {
'Content-Type': 'application/json',
},
});
});

const eventData = await getFirstSentryEnvelopeRequest<Event>(page, url);

expect(eventData?.breadcrumbs?.length).toBe(1);

expect(eventData!.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'fetch',
type: 'http',
data: {
method: 'POST',
status_code: 200,
url: 'http://sentry-test.io/foo',
__span: expect.any(String),
'graphql.document': query,
'graphql.operation': 'query Test',
},
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import * as Sentry from '@sentry/browser';
// Must import this like this to ensure the test transformation for CDN bundles works
import { graphqlClientIntegration } from '@sentry/browser';

window.Sentry = Sentry;

Sentry.init({
dsn: 'https://[email protected]/1337',
integrations: [
Sentry.browserTracingIntegration(),
graphqlClientIntegration({
endpoints: ['http://sentry-test.io/foo'],
}),
],
tracesSampleRate: 1,
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const xhr = new XMLHttpRequest();

xhr.open('POST', 'http://sentry-test.io/foo');
xhr.setRequestHeader('Accept', 'application/json');
xhr.setRequestHeader('Content-Type', 'application/json');

const query = `query Test{
people {
name
pet
}
}`;

const requestBody = JSON.stringify({ query });
xhr.send(requestBody);
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { expect } from '@playwright/test';
import type { Event } from '@sentry/core';

import { sentryTest } from '../../../../utils/fixtures';
import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers';

// Duplicate from subject.js
const query = `query Test{
people {
name
pet
}
}`;
const queryPayload = JSON.stringify({ query });

sentryTest('should update spans for GraphQL XHR requests', async ({ getLocalTestUrl, page }) => {
if (shouldSkipTracingTest()) {
return;
}

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

await page.route('**/foo', route => {
return route.fulfill({
status: 200,
body: JSON.stringify({
people: [
{ name: 'Amy', pet: 'dog' },
{ name: 'Jay', pet: 'cat' },
],
}),
headers: {
'Content-Type': 'application/json',
},
});
});

const eventData = await getFirstSentryEnvelopeRequest<Event>(page, url);
const requestSpans = eventData.spans?.filter(({ op }) => op === 'http.client');

expect(requestSpans).toHaveLength(1);

expect(requestSpans![0]).toMatchObject({
description: 'POST http://sentry-test.io/foo (query Test)',
parent_span_id: eventData.contexts?.trace?.span_id,
span_id: expect.any(String),
start_timestamp: expect.any(Number),
timestamp: expect.any(Number),
trace_id: eventData.contexts?.trace?.trace_id,
status: 'ok',
data: {
type: 'xhr',
'http.method': 'POST',
'http.url': 'http://sentry-test.io/foo',
url: 'http://sentry-test.io/foo',
'server.address': 'sentry-test.io',
'sentry.op': 'http.client',
'sentry.origin': 'auto.http.browser',
'graphql.document': queryPayload,
},
});
});

sentryTest('should update breadcrumbs for GraphQL XHR requests', async ({ getLocalTestUrl, page }) => {
if (shouldSkipTracingTest()) {
return;
}

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

await page.route('**/foo', route => {
return route.fulfill({
status: 200,
body: JSON.stringify({
people: [
{ name: 'Amy', pet: 'dog' },
{ name: 'Jay', pet: 'cat' },
],
}),
headers: {
'Content-Type': 'application/json',
},
});
});

const eventData = await getFirstSentryEnvelopeRequest<Event>(page, url);

expect(eventData?.breadcrumbs?.length).toBe(1);

expect(eventData!.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'xhr',
type: 'http',
data: {
method: 'POST',
status_code: 200,
url: 'http://sentry-test.io/foo',
'graphql.document': query,
'graphql.operation': 'query Test',
},
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ const IMPORTED_INTEGRATION_CDN_BUNDLE_PATHS: Record<string, string> = {
reportingObserverIntegration: 'reportingobserver',
feedbackIntegration: 'feedback',
moduleMetadataIntegration: 'modulemetadata',
graphqlClientIntegration: 'graphqlclient',
// technically, this is not an integration, but let's add it anyway for simplicity
makeMultiplexedTransport: 'multiplexedtransport',
};
Expand Down
2 changes: 1 addition & 1 deletion dev-packages/e2e-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
"clean": "rimraf tmp node_modules && yarn clean:test-applications && yarn clean:pnpm",
"ci:build-matrix": "ts-node ./lib/getTestMatrix.ts",
"ci:build-matrix-optional": "ts-node ./lib/getTestMatrix.ts --optional=true",
"clean:test-applications": "rimraf --glob test-applications/**/{node_modules,dist,build,.next,.nuxt,.sveltekit,pnpm-lock.yaml,.last-run.json,test-results}",
"clean:test-applications": "rimraf --glob test-applications/**/{node_modules,dist,build,.next,.nuxt,.sveltekit,.react-router,pnpm-lock.yaml,.last-run.json,test-results}",
"clean:pnpm": "pnpm store prune"
},
"devDependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,11 @@ export const appRouter = t.router({
await new Promise(resolve => setTimeout(resolve, 400));
return { success: true };
}),
crashSomething: procedure.mutation(() => {
throw new Error('I crashed in a trpc handler');
}),
crashSomething: procedure
.input(z.object({ nested: z.object({ nested: z.object({ nested: z.string() }) }) }))
.mutation(() => {
throw new Error('I crashed in a trpc handler');
}),
dontFindSomething: procedure.mutation(() => {
throw new TRPCError({ code: 'NOT_FOUND', cause: new Error('Page not found') });
}),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,22 @@ test('Should record transaction and error for a crashing trpc handler', async ({
],
});

await expect(trpcClient.crashSomething.mutate()).rejects.toBeDefined();
await expect(trpcClient.crashSomething.mutate({ nested: { nested: { nested: 'foobar' } } })).rejects.toBeDefined();

await expect(transactionEventPromise).resolves.toBeDefined();
await expect(errorEventPromise).resolves.toBeDefined();

expect((await errorEventPromise).contexts?.trpc?.['procedure_type']).toBe('mutation');
expect((await errorEventPromise).contexts?.trpc?.['procedure_path']).toBe('crashSomething');

// Should record nested context
expect((await errorEventPromise).contexts?.trpc?.['input']).toEqual({
nested: {
nested: {
nested: 'foobar',
},
},
});
});

test('Should record transaction and error for a trpc handler that returns a status code', async ({ baseURL }) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*

/test-results/
/playwright-report/
/playwright/.cache/

!*.d.ts

# react router
.react-router
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@sentry:registry=http://127.0.0.1:4873
@sentry-internal:registry=http://127.0.0.1:4873
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
html,
body {
@media (prefers-color-scheme: dark) {
color-scheme: dark;
}
}
Loading

0 comments on commit 1a21bdf

Please sign in to comment.