Skip to content

Commit

Permalink
Merge pull request #12675 from getsentry/prepare-release/8.13.0
Browse files Browse the repository at this point in the history
meta(changelog): Update changelog for 8.13.0
  • Loading branch information
andreiborza authored Jun 27, 2024
2 parents 7e29803 + e0f995f commit 8802799
Show file tree
Hide file tree
Showing 137 changed files with 1,499 additions and 714 deletions.
3 changes: 3 additions & 0 deletions .craft.yml
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ targets:
- name: npm
id: '@sentry/bun'
includeNames: /^sentry-bun-\d.*\.tgz$/
- name: npm
id: '@sentry/nestjs'
includeNames: /^sentry-nestjs-\d.*\.tgz$/

## 6. Fullstack/Meta Frameworks (depending on Node and Browser or Framework SDKs)
- name: npm
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1067,7 +1067,7 @@ jobs:
'generic-ts3.8',
'node-fastify',
'node-hapi',
'node-nestjs',
'nestjs',
'node-exports-test-app',
'node-koa',
'node-connect',
Expand Down
4 changes: 2 additions & 2 deletions .size-limit.js
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ module.exports = [
import: createImport('init'),
ignore: [...builtinModules, ...nodePrefixedBuiltinModules],
gzip: true,
limit: '135 KB',
limit: '140 KB',
},
{
name: '@sentry/node - without tracing',
Expand All @@ -237,7 +237,7 @@ module.exports = [
import: createImport('init'),
ignore: [...builtinModules, ...nodePrefixedBuiltinModules],
gzip: true,
limit: '125 KB',
limit: '130 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

## 8.13.0

### Important Changes

- **feat(nestjs): Add Nest SDK** This release adds a dedicated SDK for [NestJS](https://nestjs.com/) (`@sentry/nestjs`)
in alpha state. The SDK is a drop-in replacement for the Sentry Node SDK (`@sentry/node`) supporting the same set of
features. See the [docs](https://docs.sentry.io/platforms/javascript/guides/nestjs/) for how to use the SDK.

### Other Changes

- deps: Bump bundler plugins to `2.20.1` (#12641)
- deps(nextjs): Remove react peer dep and allow rc (#12670)
- feat: Update OTEL deps (#12635)
- feat(deps): bump @prisma/instrumentation from 5.15.0 to 5.15.1 (#12627)
- feat(node): Add context info for missing instrumentation (#12639)
- fix(feedback): Improve feedback error message (#12647)

## 8.12.0

### Important Changes
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,11 @@ Our program is currently running on an invitation basis. If you're interested in
to security@sentry.io and tell us, that you are interested in auditing this repository.

For more details, please have a look at https://sentry.io/security/#vulnerability-disclosure.

## Contributors

Thanks to everyone who contributed to the Sentry JavaScript SDK!

<a href="https://github.com/getsentry/sentry-javascript/graphs/contributors">
<img src="https://contributors-img.web.app/image?repo=getsentry/sentry-javascript" />
</a>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "node-nestjs",
"name": "nestjs",
"version": "0.0.1",
"private": true,
"scripts": {
Expand All @@ -18,7 +18,7 @@
"@nestjs/common": "^10.0.0",
"@nestjs/core": "^10.0.0",
"@nestjs/platform-express": "^10.0.0",
"@sentry/node": "latest || *",
"@sentry/nestjs": "latest || *",
"@sentry/types": "latest || *",
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Injectable } from '@nestjs/common';
import * as Sentry from '@sentry/node';
import * as Sentry from '@sentry/nestjs';
import { makeHttpRequest } from './utils';

@Injectable()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as Sentry from '@sentry/node';
import * as Sentry from '@sentry/nestjs';

Sentry.init({
environment: 'qa', // dynamic sampling bias to keep transactions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import './instrument';

// Import other modules
import { BaseExceptionFilter, HttpAdapterHost, NestFactory } from '@nestjs/core';
import * as Sentry from '@sentry/node';
import * as Sentry from '@sentry/nestjs';
import { AppModule1, AppModule2 } from './app.module';

const app1Port = 3030;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@ import { startEventProxyServer } from '@sentry-internal/test-utils';

startEventProxyServer({
port: 3031,
proxyServerName: 'node-nestjs',
proxyServerName: 'nestjs',
});
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { expect, test } from '@playwright/test';
import { waitForError } from '@sentry-internal/test-utils';

test('Sends exception to Sentry', async ({ baseURL }) => {
const errorEventPromise = waitForError('node-nestjs', event => {
const errorEventPromise = waitForError('nestjs', event => {
return !event.type && event.exception?.values?.[0]?.value === 'This is an exception with id 123';
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import { SpanJSON } from '@sentry/types';
test('Propagates trace for outgoing http requests', async ({ baseURL }) => {
const id = crypto.randomUUID();

const inboundTransactionPromise = waitForTransaction('node-nestjs', transactionEvent => {
const inboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => {
return (
transactionEvent.contexts?.trace?.op === 'http.server' &&
transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-inbound-headers/${id}`
);
});

const outboundTransactionPromise = waitForTransaction('node-nestjs', transactionEvent => {
const outboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => {
return (
transactionEvent.contexts?.trace?.op === 'http.server' &&
transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-outgoing-http/${id}`
Expand Down Expand Up @@ -121,14 +121,14 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => {
test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => {
const id = crypto.randomUUID();

const inboundTransactionPromise = waitForTransaction('node-nestjs', transactionEvent => {
const inboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => {
return (
transactionEvent?.contexts?.trace?.op === 'http.server' &&
transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-inbound-headers/${id}`
);
});

const outboundTransactionPromise = waitForTransaction('node-nestjs', transactionEvent => {
const outboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => {
return (
transactionEvent?.contexts?.trace?.op === 'http.server' &&
transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-outgoing-fetch/${id}`
Expand Down Expand Up @@ -234,7 +234,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => {
});

test('Propagates trace for outgoing external http requests', async ({ baseURL }) => {
const inboundTransactionPromise = waitForTransaction('node-nestjs', transactionEvent => {
const inboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => {
return (
transactionEvent?.contexts?.trace?.op === 'http.server' &&
transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-outgoing-http-external-allowed`
Expand Down Expand Up @@ -271,7 +271,7 @@ test('Propagates trace for outgoing external http requests', async ({ baseURL })
});

test('Does not propagate outgoing http requests not covered by tracePropagationTargets', async ({ baseURL }) => {
const inboundTransactionPromise = waitForTransaction('node-nestjs', transactionEvent => {
const inboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => {
return (
transactionEvent?.contexts?.trace?.op === 'http.server' &&
transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-outgoing-http-external-disallowed`
Expand All @@ -295,7 +295,7 @@ test('Does not propagate outgoing http requests not covered by tracePropagationT
});

test('Propagates trace for outgoing external fetch requests', async ({ baseURL }) => {
const inboundTransactionPromise = waitForTransaction('node-nestjs', transactionEvent => {
const inboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => {
return (
transactionEvent?.contexts?.trace?.op === 'http.server' &&
transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-outgoing-fetch-external-allowed`
Expand Down Expand Up @@ -332,7 +332,7 @@ test('Propagates trace for outgoing external fetch requests', async ({ baseURL }
});

test('Does not propagate outgoing fetch requests not covered by tracePropagationTargets', async ({ baseURL }) => {
const inboundTransactionPromise = waitForTransaction('node-nestjs', transactionEvent => {
const inboundTransactionPromise = waitForTransaction('nestjs', transactionEvent => {
return (
transactionEvent?.contexts?.trace?.op === 'http.server' &&
transactionEvent.contexts?.trace?.data?.['http.target'] === `/test-outgoing-fetch-external-disallowed`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { expect, test } from '@playwright/test';
import { waitForTransaction } from '@sentry-internal/test-utils';

test('Sends an API route transaction', async ({ baseURL }) => {
const pageloadTransactionEventPromise = waitForTransaction('node-nestjs', transactionEvent => {
const pageloadTransactionEventPromise = waitForTransaction('nestjs', transactionEvent => {
return (
transactionEvent?.contexts?.trace?.op === 'http.server' &&
transactionEvent?.transaction === 'GET /test-transaction'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist
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,32 @@
{
"name": "node-express-incorrect-instrumentation",
"version": "1.0.0",
"private": true,
"scripts": {
"build": "tsc",
"start": "node dist/app.js",
"test": "playwright test",
"clean": "npx rimraf node_modules pnpm-lock.yaml",
"test:build": "pnpm install && pnpm build",
"test:assert": "pnpm test"
},
"dependencies": {
"@sentry/core": "latest || *",
"@sentry/node": "latest || *",
"@sentry/types": "latest || *",
"@trpc/server": "10.45.2",
"@trpc/client": "10.45.2",
"@types/express": "4.17.17",
"@types/node": "18.15.1",
"express": "4.19.2",
"typescript": "4.9.5",
"zod": "~3.22.4"
},
"devDependencies": {
"@playwright/test": "^1.44.1",
"@sentry-internal/test-utils": "link:../../../test-utils"
},
"volta": {
"extends": "../../package.json"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { getPlaywrightConfig } from '@sentry-internal/test-utils';

const config = getPlaywrightConfig({
startCommand: `pnpm start`,
});

export default config;
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
declare global {
namespace globalThis {
var transactionIds: string[];
}
}

import express from 'express';

const app = express();
const port = 3030;

// import and init sentry last for missing instrumentation
import * as Sentry from '@sentry/node';
Sentry.init({
environment: 'qa', // dynamic sampling bias to keep transactions
dsn: process.env.E2E_TEST_DSN,
includeLocalVariables: true,
debug: !!process.env.DEBUG,
tunnel: `http://localhost:3031/`, // proxy server
tracesSampleRate: 1,
});

app.get('/test-exception/:id', function (req, _res) {
throw new Error(`This is an exception with id ${req.params.id}`);
});

Sentry.setupExpressErrorHandler(app);

// @ts-ignore
app.use(function onError(err, req, res, next) {
// The error id is attached to `res.sentry` to be returned
// and optionally displayed to the user for support.
res.statusCode = 500;
res.end(res.sentry + '\n');
});

app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { startEventProxyServer } from '@sentry-internal/test-utils';

startEventProxyServer({
port: 3031,
proxyServerName: 'node-express',
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { expect, test } from '@playwright/test';
import { waitForError } from '@sentry-internal/test-utils';

test('Sends correct context when instrumentation was set up incorrectly', async ({ baseURL }) => {
const errorEventPromise = waitForError('node-express', event => {
return !event.type && event.exception?.values?.[0]?.value === 'This is an exception with id 123';
});

await fetch(`${baseURL}/test-exception/123`);

const errorEvent = await errorEventPromise;

expect(errorEvent.exception?.values).toHaveLength(1);
expect(errorEvent.exception?.values?.[0]?.value).toBe('This is an exception with id 123');

expect(errorEvent.contexts?.missing_instrumentation).toEqual({
package: 'express',
'javascript.is_cjs': true,
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"types": ["node"],
"esModuleInterop": true,
"lib": ["es2018"],
"strict": true,
"outDir": "dist"
},
"include": ["src/**/*.ts"]
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect, test } from '@playwright/test';
import { waitForTransaction } from '@sentry-internal/test-utils';
import { waitForEnvelopeItem, waitForTransaction } from '@sentry-internal/test-utils';

test('sends a pageload transaction with a parameterized URL', async ({ page }) => {
const transactionPromise = waitForTransaction('react-router-6', async transactionEvent => {
Expand Down Expand Up @@ -54,3 +54,45 @@ test('sends a navigation transaction with a parameterized URL', async ({ page })
},
});
});

test('sends an INP span', async ({ page }) => {
const inpSpanPromise = waitForEnvelopeItem('react-router-6', item => {
return item[0].type === 'span';
});

await page.goto(`/`);

await page.click('#exception-button');

await page.waitForTimeout(500);

// Page hide to trigger INP
await page.evaluate(() => {
window.dispatchEvent(new Event('pagehide'));
});

const inpSpan = await inpSpanPromise;

expect(inpSpan[1]).toEqual({
data: {
'sentry.origin': 'auto.http.browser.inp',
'sentry.op': 'ui.interaction.click',
release: 'e2e-test',
environment: 'qa',
transaction: '/',
'sentry.exclusive_time': expect.any(Number),
replay_id: expect.any(String),
},
description: 'body > div#root > input#exception-button[type="button"]',
op: 'ui.interaction.click',
parent_span_id: expect.any(String),
span_id: expect.any(String),
start_timestamp: expect.any(Number),
timestamp: expect.any(Number),
trace_id: expect.any(String),
origin: 'auto.http.browser.inp',
exclusive_time: expect.any(Number),
measurements: { inp: { unit: 'millisecond', value: expect.any(Number) } },
segment_id: expect.any(String),
});
});
Loading

0 comments on commit 8802799

Please sign in to comment.