From 0f6ef9abd60f844e51cef03d7c88b829a10e88c4 Mon Sep 17 00:00:00 2001 From: Francesco Gringl-Novy Date: Mon, 16 Dec 2024 11:29:25 +0100 Subject: [PATCH 01/66] ci(v8): Ensure CI runs on v8 & v9 branches (#14604) (#14727) In order for us to have size-limit comparison etc, we need to ensure CI runs on v8 & v9 branches too. Picking this from develop so we also have this on v8 branch! --- .github/workflows/build.yml | 10 ++++++---- .github/workflows/enforce-license-compliance.yml | 13 +++++++++++-- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bf9ba21376bb..31f5cea28bda 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,6 +4,8 @@ on: branches: - develop - master + - v9 + - v8 - release/** pull_request: merge_group: @@ -105,7 +107,7 @@ jobs: outputs: commit_label: '${{ env.COMMIT_SHA }}: ${{ env.COMMIT_MESSAGE }}' # Note: These next three have to be checked as strings ('true'/'false')! - is_develop: ${{ github.ref == 'refs/heads/develop' }} + is_base_branch: ${{ github.ref == 'refs/heads/develop' || github.ref == 'refs/heads/v9' || github.ref == 'refs/heads/v8'}} is_release: ${{ startsWith(github.ref, 'refs/heads/release/') }} changed_profiling_node: ${{ steps.changed.outputs.profiling_node == 'true' }} changed_ci: ${{ steps.changed.outputs.workflow == 'true' }} @@ -126,7 +128,7 @@ jobs: timeout-minutes: 15 if: | needs.job_get_metadata.outputs.changed_any_code == 'true' || - needs.job_get_metadata.outputs.is_develop == 'true' || + needs.job_get_metadata.outputs.is_base_branch == 'true' || needs.job_get_metadata.outputs.is_release == 'true' || (needs.job_get_metadata.outputs.is_gitflow_sync == 'false' && needs.job_get_metadata.outputs.has_gitflow_label == 'false') steps: @@ -171,7 +173,7 @@ jobs: key: nx-Linux-${{ github.ref }}-${{ env.HEAD_COMMIT || github.sha }} # On develop branch, we want to _store_ the cache (so it can be used by other branches), but never _restore_ from it restore-keys: - ${{needs.job_get_metadata.outputs.is_develop == 'false' && env.NX_CACHE_RESTORE_KEYS || 'nx-never-restore'}} + ${{needs.job_get_metadata.outputs.is_base_branch == 'false' && env.NX_CACHE_RESTORE_KEYS || 'nx-never-restore'}} - name: Build packages # Set the CODECOV_TOKEN for Bundle Analysis @@ -219,7 +221,7 @@ jobs: timeout-minutes: 15 runs-on: ubuntu-20.04 if: - github.event_name == 'pull_request' || needs.job_get_metadata.outputs.is_develop == 'true' || + github.event_name == 'pull_request' || needs.job_get_metadata.outputs.is_base_branch == 'true' || needs.job_get_metadata.outputs.is_release == 'true' steps: - name: Check out current commit (${{ needs.job_get_metadata.outputs.commit_label }}) diff --git a/.github/workflows/enforce-license-compliance.yml b/.github/workflows/enforce-license-compliance.yml index 8f63b6ca063b..776f8135178d 100644 --- a/.github/workflows/enforce-license-compliance.yml +++ b/.github/workflows/enforce-license-compliance.yml @@ -2,9 +2,18 @@ name: "CI: Enforce License Compliance" on: push: - branches: [master, develop, release/*] + branches: + - develop + - master + - v9 + - v8 + - release/** pull_request: - branches: [master, develop] + branches: + - develop + - master + - v9 + - v8 jobs: enforce-license-compliance: From 323a38c24d15c1bea77a07839bad1fb3aee0f774 Mon Sep 17 00:00:00 2001 From: Andrei <168741329+andreiborza@users.noreply.github.com> Date: Mon, 16 Dec 2024 12:36:56 +0100 Subject: [PATCH 02/66] meta(changelog): Update changelog for 8.45.1 (#14722) This release also publishes the AWS lambda layer under the current, non-version-suffixed layer since it's lagging behind since `8.42.0` with the introduction of the v8-suffixed layer. --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index dd6332f4c125..c3f0e52db2e6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,10 @@ - "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott +## 8.45.1 + +- fix(feedback): Return when the `sendFeedback` promise resolves ([#14683](https://github.com/getsentry/sentry-javascript/pull/14683)) + ## 8.45.0 - feat(core): Add `handled` option to `captureConsoleIntegration` ([#14664](https://github.com/getsentry/sentry-javascript/pull/14664)) From 3690d620539f9995eb0559ca8f622df9dedea03e Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Mon, 16 Dec 2024 11:56:08 +0000 Subject: [PATCH 03/66] release: 8.45.1 --- .../browser-integration-tests/package.json | 4 ++-- .../bundle-analyzer-scenarios/package.json | 2 +- dev-packages/clear-cache-gh-action/package.json | 2 +- dev-packages/e2e-tests/package.json | 2 +- .../external-contributor-gh-action/package.json | 2 +- dev-packages/node-integration-tests/package.json | 8 ++++---- dev-packages/rollup-utils/package.json | 2 +- dev-packages/size-limit-gh-action/package.json | 2 +- dev-packages/test-utils/package.json | 4 ++-- lerna.json | 2 +- packages/angular/package.json | 6 +++--- packages/astro/package.json | 8 ++++---- packages/aws-serverless/package.json | 6 +++--- packages/browser-utils/package.json | 4 ++-- packages/browser/package.json | 14 +++++++------- packages/bun/package.json | 8 ++++---- packages/cloudflare/package.json | 4 ++-- packages/core/package.json | 2 +- packages/deno/package.json | 4 ++-- packages/ember/package.json | 6 +++--- packages/eslint-config-sdk/package.json | 6 +++--- packages/eslint-plugin-sdk/package.json | 2 +- packages/feedback/package.json | 4 ++-- packages/gatsby/package.json | 6 +++--- packages/google-cloud-serverless/package.json | 6 +++--- packages/integration-shims/package.json | 4 ++-- packages/nestjs/package.json | 6 +++--- packages/nextjs/package.json | 14 +++++++------- packages/nitro-utils/package.json | 4 ++-- packages/node/package.json | 6 +++--- packages/nuxt/package.json | 12 ++++++------ packages/opentelemetry/package.json | 4 ++-- packages/profiling-node/package.json | 6 +++--- packages/react/package.json | 6 +++--- packages/remix/package.json | 10 +++++----- packages/replay-canvas/package.json | 6 +++--- packages/replay-internal/package.json | 8 ++++---- packages/replay-worker/package.json | 2 +- packages/solid/package.json | 6 +++--- packages/solidstart/package.json | 10 +++++----- packages/svelte/package.json | 6 +++--- packages/sveltekit/package.json | 10 +++++----- packages/types/package.json | 4 ++-- packages/typescript/package.json | 2 +- packages/utils/package.json | 4 ++-- packages/vercel-edge/package.json | 6 +++--- packages/vue/package.json | 6 +++--- packages/wasm/package.json | 6 +++--- 48 files changed, 132 insertions(+), 132 deletions(-) diff --git a/dev-packages/browser-integration-tests/package.json b/dev-packages/browser-integration-tests/package.json index 31a7ce76727e..20ea83b4b210 100644 --- a/dev-packages/browser-integration-tests/package.json +++ b/dev-packages/browser-integration-tests/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/browser-integration-tests", - "version": "8.45.0", + "version": "8.45.1", "main": "index.js", "license": "MIT", "engines": { @@ -43,7 +43,7 @@ "@babel/preset-typescript": "^7.16.7", "@playwright/test": "^1.44.1", "@sentry-internal/rrweb": "2.31.0", - "@sentry/browser": "8.45.0", + "@sentry/browser": "8.45.1", "axios": "1.7.7", "babel-loader": "^8.2.2", "html-webpack-plugin": "^5.5.0", diff --git a/dev-packages/bundle-analyzer-scenarios/package.json b/dev-packages/bundle-analyzer-scenarios/package.json index c5146697c4d4..7c2b0f0dfdc4 100644 --- a/dev-packages/bundle-analyzer-scenarios/package.json +++ b/dev-packages/bundle-analyzer-scenarios/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/bundle-analyzer-scenarios", - "version": "8.45.0", + "version": "8.45.1", "description": "Scenarios to test bundle analysis with", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/dev-packages/bundle-analyzer-scenarios", diff --git a/dev-packages/clear-cache-gh-action/package.json b/dev-packages/clear-cache-gh-action/package.json index acf92547dca5..7e624b474216 100644 --- a/dev-packages/clear-cache-gh-action/package.json +++ b/dev-packages/clear-cache-gh-action/package.json @@ -1,7 +1,7 @@ { "name": "@sentry-internal/clear-cache-gh-action", "description": "An internal Github Action to clear GitHub caches.", - "version": "8.45.0", + "version": "8.45.1", "license": "MIT", "engines": { "node": ">=18" diff --git a/dev-packages/e2e-tests/package.json b/dev-packages/e2e-tests/package.json index 6452d7752eba..2f0f686f2179 100644 --- a/dev-packages/e2e-tests/package.json +++ b/dev-packages/e2e-tests/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/e2e-tests", - "version": "8.45.0", + "version": "8.45.1", "license": "MIT", "private": true, "scripts": { diff --git a/dev-packages/external-contributor-gh-action/package.json b/dev-packages/external-contributor-gh-action/package.json index a4857bd41082..6831ccd89718 100644 --- a/dev-packages/external-contributor-gh-action/package.json +++ b/dev-packages/external-contributor-gh-action/package.json @@ -1,7 +1,7 @@ { "name": "@sentry-internal/external-contributor-gh-action", "description": "An internal Github Action to add external contributors to the CHANGELOG.md file.", - "version": "8.45.0", + "version": "8.45.1", "license": "MIT", "engines": { "node": ">=18" diff --git a/dev-packages/node-integration-tests/package.json b/dev-packages/node-integration-tests/package.json index 24be97583c1c..8c52cfbb03be 100644 --- a/dev-packages/node-integration-tests/package.json +++ b/dev-packages/node-integration-tests/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/node-integration-tests", - "version": "8.45.0", + "version": "8.45.1", "license": "MIT", "engines": { "node": ">=14.18" @@ -31,9 +31,9 @@ "@nestjs/core": "10.4.6", "@nestjs/platform-express": "10.4.6", "@prisma/client": "5.9.1", - "@sentry/aws-serverless": "8.45.0", - "@sentry/core": "8.45.0", - "@sentry/node": "8.45.0", + "@sentry/aws-serverless": "8.45.1", + "@sentry/core": "8.45.1", + "@sentry/node": "8.45.1", "@types/mongodb": "^3.6.20", "@types/mysql": "^2.15.21", "@types/pg": "^8.6.5", diff --git a/dev-packages/rollup-utils/package.json b/dev-packages/rollup-utils/package.json index 763f043da327..36d8b82c5457 100644 --- a/dev-packages/rollup-utils/package.json +++ b/dev-packages/rollup-utils/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/rollup-utils", - "version": "8.45.0", + "version": "8.45.1", "description": "Rollup utilities used at Sentry for the Sentry JavaScript SDK", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/rollup-utils", diff --git a/dev-packages/size-limit-gh-action/package.json b/dev-packages/size-limit-gh-action/package.json index c40c18645d6a..01555aff7e3f 100644 --- a/dev-packages/size-limit-gh-action/package.json +++ b/dev-packages/size-limit-gh-action/package.json @@ -1,7 +1,7 @@ { "name": "@sentry-internal/size-limit-gh-action", "description": "An internal Github Action to compare the current size of a PR against the one on develop.", - "version": "8.45.0", + "version": "8.45.1", "license": "MIT", "engines": { "node": ">=18" diff --git a/dev-packages/test-utils/package.json b/dev-packages/test-utils/package.json index 09ad4cf5a55d..6d5bb7e0f073 100644 --- a/dev-packages/test-utils/package.json +++ b/dev-packages/test-utils/package.json @@ -1,6 +1,6 @@ { "private": true, - "version": "8.45.0", + "version": "8.45.1", "name": "@sentry-internal/test-utils", "author": "Sentry", "license": "MIT", @@ -45,7 +45,7 @@ }, "devDependencies": { "@playwright/test": "^1.44.1", - "@sentry/core": "8.45.0" + "@sentry/core": "8.45.1" }, "volta": { "extends": "../../package.json" diff --git a/lerna.json b/lerna.json index febf4090d555..d1d73317d6a6 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", - "version": "8.45.0", + "version": "8.45.1", "npmClient": "yarn" } diff --git a/packages/angular/package.json b/packages/angular/package.json index 06bb0492c2f7..4c7b6c2e996c 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/angular", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for Angular", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/angular", @@ -21,8 +21,8 @@ "rxjs": "^6.5.5 || ^7.x" }, "dependencies": { - "@sentry/browser": "8.45.0", - "@sentry/core": "8.45.0", + "@sentry/browser": "8.45.1", + "@sentry/core": "8.45.1", "tslib": "^2.4.1" }, "devDependencies": { diff --git a/packages/astro/package.json b/packages/astro/package.json index 43c374a766cc..3d8ff8bd75c4 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/astro", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for Astro", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/astro", @@ -56,9 +56,9 @@ "astro": ">=3.x || >=4.0.0-beta || >=5.x" }, "dependencies": { - "@sentry/browser": "8.45.0", - "@sentry/core": "8.45.0", - "@sentry/node": "8.45.0", + "@sentry/browser": "8.45.1", + "@sentry/core": "8.45.1", + "@sentry/node": "8.45.1", "@sentry/vite-plugin": "^2.22.6" }, "devDependencies": { diff --git a/packages/aws-serverless/package.json b/packages/aws-serverless/package.json index 856a7dc4f51f..92a2fe02eb36 100644 --- a/packages/aws-serverless/package.json +++ b/packages/aws-serverless/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/aws-serverless", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for AWS Lambda and AWS Serverless Environments", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/serverless", @@ -68,8 +68,8 @@ "@opentelemetry/instrumentation": "^0.56.0", "@opentelemetry/instrumentation-aws-lambda": "0.49.0", "@opentelemetry/instrumentation-aws-sdk": "0.48.0", - "@sentry/core": "8.45.0", - "@sentry/node": "8.45.0", + "@sentry/core": "8.45.1", + "@sentry/node": "8.45.1", "@types/aws-lambda": "^8.10.62" }, "devDependencies": { diff --git a/packages/browser-utils/package.json b/packages/browser-utils/package.json index 15d5bde00065..a85449e7ea1a 100644 --- a/packages/browser-utils/package.json +++ b/packages/browser-utils/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/browser-utils", - "version": "8.45.0", + "version": "8.45.1", "description": "Browser Utilities for all Sentry JavaScript SDKs", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/browser-utils", @@ -39,7 +39,7 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.45.0" + "@sentry/core": "8.45.1" }, "scripts": { "build": "run-p build:transpile build:types", diff --git a/packages/browser/package.json b/packages/browser/package.json index f588f2801eb0..371533f5f84e 100644 --- a/packages/browser/package.json +++ b/packages/browser/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/browser", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for browsers", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/browser", @@ -39,14 +39,14 @@ "access": "public" }, "dependencies": { - "@sentry-internal/browser-utils": "8.45.0", - "@sentry-internal/feedback": "8.45.0", - "@sentry-internal/replay": "8.45.0", - "@sentry-internal/replay-canvas": "8.45.0", - "@sentry/core": "8.45.0" + "@sentry-internal/browser-utils": "8.45.1", + "@sentry-internal/feedback": "8.45.1", + "@sentry-internal/replay": "8.45.1", + "@sentry-internal/replay-canvas": "8.45.1", + "@sentry/core": "8.45.1" }, "devDependencies": { - "@sentry-internal/integration-shims": "8.45.0", + "@sentry-internal/integration-shims": "8.45.1", "fake-indexeddb": "^4.0.1" }, "scripts": { diff --git a/packages/bun/package.json b/packages/bun/package.json index ce1c85cbcd0f..d88bd81a68d4 100644 --- a/packages/bun/package.json +++ b/packages/bun/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/bun", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for bun", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/bun", @@ -39,9 +39,9 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.45.0", - "@sentry/node": "8.45.0", - "@sentry/opentelemetry": "8.45.0" + "@sentry/core": "8.45.1", + "@sentry/node": "8.45.1", + "@sentry/opentelemetry": "8.45.1" }, "devDependencies": { "bun-types": "latest" diff --git a/packages/cloudflare/package.json b/packages/cloudflare/package.json index efec51c5c0f5..7281d39677a3 100644 --- a/packages/cloudflare/package.json +++ b/packages/cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/cloudflare", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for Cloudflare Workers and Pages", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/cloudflare", @@ -39,7 +39,7 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.45.0" + "@sentry/core": "8.45.1" }, "optionalDependencies": { "@cloudflare/workers-types": "^4.x" diff --git a/packages/core/package.json b/packages/core/package.json index ab43b79117b9..852e15913fc3 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/core", - "version": "8.45.0", + "version": "8.45.1", "description": "Base implementation for all Sentry JavaScript SDKs", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/core", diff --git a/packages/deno/package.json b/packages/deno/package.json index b9f7dbdc8ea8..19a8d2cbfc00 100644 --- a/packages/deno/package.json +++ b/packages/deno/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/deno", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for Deno", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/deno", @@ -24,7 +24,7 @@ "/build" ], "dependencies": { - "@sentry/core": "8.45.0" + "@sentry/core": "8.45.1" }, "devDependencies": { "@rollup/plugin-typescript": "^11.1.5", diff --git a/packages/ember/package.json b/packages/ember/package.json index 1547eed88d94..25adb5a21692 100644 --- a/packages/ember/package.json +++ b/packages/ember/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/ember", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for Ember.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/ember", @@ -32,8 +32,8 @@ "dependencies": { "@babel/core": "^7.24.4", "@embroider/macros": "^1.16.0", - "@sentry/browser": "8.45.0", - "@sentry/core": "8.45.0", + "@sentry/browser": "8.45.1", + "@sentry/core": "8.45.1", "ember-auto-import": "^2.7.2", "ember-cli-babel": "^8.2.0", "ember-cli-htmlbars": "^6.1.1", diff --git a/packages/eslint-config-sdk/package.json b/packages/eslint-config-sdk/package.json index 246f51ed6dcf..cc8568825bea 100644 --- a/packages/eslint-config-sdk/package.json +++ b/packages/eslint-config-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/eslint-config-sdk", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK eslint config", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/eslint-config-sdk", @@ -22,8 +22,8 @@ "access": "public" }, "dependencies": { - "@sentry-internal/eslint-plugin-sdk": "8.45.0", - "@sentry-internal/typescript": "8.45.0", + "@sentry-internal/eslint-plugin-sdk": "8.45.1", + "@sentry-internal/typescript": "8.45.1", "@typescript-eslint/eslint-plugin": "^5.48.0", "@typescript-eslint/parser": "^5.48.0", "eslint-config-prettier": "^6.11.0", diff --git a/packages/eslint-plugin-sdk/package.json b/packages/eslint-plugin-sdk/package.json index 7a6a729fc0cd..aa7360ae1d21 100644 --- a/packages/eslint-plugin-sdk/package.json +++ b/packages/eslint-plugin-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/eslint-plugin-sdk", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK eslint plugin", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/eslint-plugin-sdk", diff --git a/packages/feedback/package.json b/packages/feedback/package.json index a5e44856378e..2d0f76b55038 100644 --- a/packages/feedback/package.json +++ b/packages/feedback/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/feedback", - "version": "8.45.0", + "version": "8.45.1", "description": "Sentry SDK integration for user feedback", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/feedback", @@ -39,7 +39,7 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.45.0" + "@sentry/core": "8.45.1" }, "devDependencies": { "preact": "^10.19.4" diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index 2c03fae30f14..8645462f1492 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/gatsby", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for Gatsby.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/gatsby", @@ -45,8 +45,8 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.45.0", - "@sentry/react": "8.45.0", + "@sentry/core": "8.45.1", + "@sentry/react": "8.45.1", "@sentry/webpack-plugin": "2.22.7" }, "peerDependencies": { diff --git a/packages/google-cloud-serverless/package.json b/packages/google-cloud-serverless/package.json index 52008df49931..f23b69985aa6 100644 --- a/packages/google-cloud-serverless/package.json +++ b/packages/google-cloud-serverless/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/google-cloud-serverless", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for Google Cloud Functions", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/google-cloud-serverless", @@ -48,8 +48,8 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.45.0", - "@sentry/node": "8.45.0", + "@sentry/core": "8.45.1", + "@sentry/node": "8.45.1", "@types/express": "^4.17.14" }, "devDependencies": { diff --git a/packages/integration-shims/package.json b/packages/integration-shims/package.json index 322922a945a0..091770cb3bed 100644 --- a/packages/integration-shims/package.json +++ b/packages/integration-shims/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/integration-shims", - "version": "8.45.0", + "version": "8.45.1", "description": "Shims for integrations in Sentry SDK.", "main": "build/cjs/index.js", "module": "build/esm/index.js", @@ -55,7 +55,7 @@ "url": "https://github.com/getsentry/sentry-javascript/issues" }, "dependencies": { - "@sentry/core": "8.45.0" + "@sentry/core": "8.45.1" }, "engines": { "node": ">=14.18" diff --git a/packages/nestjs/package.json b/packages/nestjs/package.json index 1bef4cc56c2f..b266bd65a836 100644 --- a/packages/nestjs/package.json +++ b/packages/nestjs/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/nestjs", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for NestJS", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/nestjs", @@ -44,8 +44,8 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.45.0", - "@sentry/node": "8.45.0" + "@sentry/core": "8.45.1", + "@sentry/node": "8.45.1" }, "devDependencies": { "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json index baafbe149a1d..335371c7a827 100644 --- a/packages/nextjs/package.json +++ b/packages/nextjs/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/nextjs", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for Next.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/nextjs", @@ -79,12 +79,12 @@ "@opentelemetry/api": "^1.9.0", "@opentelemetry/semantic-conventions": "^1.28.0", "@rollup/plugin-commonjs": "28.0.1", - "@sentry-internal/browser-utils": "8.45.0", - "@sentry/core": "8.45.0", - "@sentry/node": "8.45.0", - "@sentry/opentelemetry": "8.45.0", - "@sentry/react": "8.45.0", - "@sentry/vercel-edge": "8.45.0", + "@sentry-internal/browser-utils": "8.45.1", + "@sentry/core": "8.45.1", + "@sentry/node": "8.45.1", + "@sentry/opentelemetry": "8.45.1", + "@sentry/react": "8.45.1", + "@sentry/vercel-edge": "8.45.1", "@sentry/webpack-plugin": "2.22.7", "chalk": "3.0.0", "resolve": "1.22.8", diff --git a/packages/nitro-utils/package.json b/packages/nitro-utils/package.json index 06ec390ef87f..1d238b503c5c 100644 --- a/packages/nitro-utils/package.json +++ b/packages/nitro-utils/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/nitro-utils", - "version": "8.45.0", + "version": "8.45.1", "description": "Utilities for all Sentry SDKs with Nitro on the server-side", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/nitro-utils", @@ -37,7 +37,7 @@ } }, "dependencies": { - "@sentry/core": "8.45.0" + "@sentry/core": "8.45.1" }, "devDependencies": { "rollup": "^4.24.4" diff --git a/packages/node/package.json b/packages/node/package.json index 618b9aa89725..c8c9a6996adf 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/node", - "version": "8.45.0", + "version": "8.45.1", "description": "Sentry Node SDK using OpenTelemetry for performance instrumentation", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/node", @@ -97,8 +97,8 @@ "@opentelemetry/sdk-trace-base": "^1.29.0", "@opentelemetry/semantic-conventions": "^1.28.0", "@prisma/instrumentation": "5.19.1", - "@sentry/core": "8.45.0", - "@sentry/opentelemetry": "8.45.0", + "@sentry/core": "8.45.1", + "@sentry/opentelemetry": "8.45.1", "import-in-the-middle": "^1.11.2" }, "devDependencies": { diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index 86ce75ba76f8..714e3abbbb5a 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/nuxt", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for Nuxt (EXPERIMENTAL)", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/nuxt", @@ -43,13 +43,13 @@ }, "dependencies": { "@nuxt/kit": "^3.13.2", - "@sentry/browser": "8.45.0", - "@sentry/core": "8.45.0", - "@sentry/node": "8.45.0", - "@sentry/opentelemetry": "8.45.0", + "@sentry/browser": "8.45.1", + "@sentry/core": "8.45.1", + "@sentry/node": "8.45.1", + "@sentry/opentelemetry": "8.45.1", "@sentry/rollup-plugin": "2.22.7", "@sentry/vite-plugin": "2.22.6", - "@sentry/vue": "8.45.0" + "@sentry/vue": "8.45.1" }, "devDependencies": { "@nuxt/module-builder": "^0.8.4", diff --git a/packages/opentelemetry/package.json b/packages/opentelemetry/package.json index e342a8d34be8..3356d3728919 100644 --- a/packages/opentelemetry/package.json +++ b/packages/opentelemetry/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/opentelemetry", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry utilities for OpenTelemetry", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/opentelemetry", @@ -39,7 +39,7 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.45.0" + "@sentry/core": "8.45.1" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0", diff --git a/packages/profiling-node/package.json b/packages/profiling-node/package.json index 19ecb062875e..349935ef762c 100644 --- a/packages/profiling-node/package.json +++ b/packages/profiling-node/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/profiling-node", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for Node.js Profiling", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/profiling-node", @@ -75,8 +75,8 @@ "test": "cross-env SENTRY_PROFILER_BINARY_DIR=lib jest --config jest.config.js" }, "dependencies": { - "@sentry/core": "8.45.0", - "@sentry/node": "8.45.0", + "@sentry/core": "8.45.1", + "@sentry/node": "8.45.1", "detect-libc": "^2.0.2", "node-abi": "^3.61.0" }, diff --git a/packages/react/package.json b/packages/react/package.json index d14ad2f112a8..e94f07db3bab 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/react", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for React.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/react", @@ -39,8 +39,8 @@ "access": "public" }, "dependencies": { - "@sentry/browser": "8.45.0", - "@sentry/core": "8.45.0", + "@sentry/browser": "8.45.1", + "@sentry/core": "8.45.1", "hoist-non-react-statics": "^3.3.2" }, "peerDependencies": { diff --git a/packages/remix/package.json b/packages/remix/package.json index 9967c77676bc..7374b71185ef 100644 --- a/packages/remix/package.json +++ b/packages/remix/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/remix", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for Remix", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/remix", @@ -55,10 +55,10 @@ "@opentelemetry/api": "^1.9.0", "@remix-run/router": "1.x", "@sentry/cli": "^2.39.1", - "@sentry/core": "8.45.0", - "@sentry/node": "8.45.0", - "@sentry/opentelemetry": "8.45.0", - "@sentry/react": "8.45.0", + "@sentry/core": "8.45.1", + "@sentry/node": "8.45.1", + "@sentry/opentelemetry": "8.45.1", + "@sentry/react": "8.45.1", "glob": "^10.3.4", "opentelemetry-instrumentation-remix": "0.8.0", "yargs": "^17.6.0" diff --git a/packages/replay-canvas/package.json b/packages/replay-canvas/package.json index 4faeb7db1ef7..33a431309eb7 100644 --- a/packages/replay-canvas/package.json +++ b/packages/replay-canvas/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/replay-canvas", - "version": "8.45.0", + "version": "8.45.1", "description": "Replay canvas integration", "main": "build/npm/cjs/index.js", "module": "build/npm/esm/index.js", @@ -68,8 +68,8 @@ "@sentry-internal/rrweb": "2.31.0" }, "dependencies": { - "@sentry-internal/replay": "8.45.0", - "@sentry/core": "8.45.0" + "@sentry-internal/replay": "8.45.1", + "@sentry/core": "8.45.1" }, "engines": { "node": ">=14.18" diff --git a/packages/replay-internal/package.json b/packages/replay-internal/package.json index 4267723b8b67..de8c0bde0cf1 100644 --- a/packages/replay-internal/package.json +++ b/packages/replay-internal/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/replay", - "version": "8.45.0", + "version": "8.45.1", "description": "User replays for Sentry", "main": "build/npm/cjs/index.js", "module": "build/npm/esm/index.js", @@ -68,7 +68,7 @@ "homepage": "https://docs.sentry.io/platforms/javascript/session-replay/", "devDependencies": { "@babel/core": "^7.17.5", - "@sentry-internal/replay-worker": "8.45.0", + "@sentry-internal/replay-worker": "8.45.1", "@sentry-internal/rrweb": "2.31.0", "@sentry-internal/rrweb-snapshot": "2.31.0", "fflate": "^0.8.1", @@ -76,8 +76,8 @@ "jsdom-worker": "^0.2.1" }, "dependencies": { - "@sentry-internal/browser-utils": "8.45.0", - "@sentry/core": "8.45.0" + "@sentry-internal/browser-utils": "8.45.1", + "@sentry/core": "8.45.1" }, "engines": { "node": ">=14.18" diff --git a/packages/replay-worker/package.json b/packages/replay-worker/package.json index 7a1596319e4f..f134839b171c 100644 --- a/packages/replay-worker/package.json +++ b/packages/replay-worker/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/replay-worker", - "version": "8.45.0", + "version": "8.45.1", "description": "Worker for @sentry-internal/replay", "main": "build/esm/index.js", "module": "build/esm/index.js", diff --git a/packages/solid/package.json b/packages/solid/package.json index f718a1374a11..93a2aeb35a91 100644 --- a/packages/solid/package.json +++ b/packages/solid/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/solid", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for Solid", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/solid", @@ -44,8 +44,8 @@ "access": "public" }, "dependencies": { - "@sentry/browser": "8.45.0", - "@sentry/core": "8.45.0" + "@sentry/browser": "8.45.1", + "@sentry/core": "8.45.1" }, "peerDependencies": { "@solidjs/router": "^0.13.4", diff --git a/packages/solidstart/package.json b/packages/solidstart/package.json index dba27d321153..72d2ad4e37e7 100644 --- a/packages/solidstart/package.json +++ b/packages/solidstart/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/solidstart", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for Solid Start", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/solidstart", @@ -66,10 +66,10 @@ } }, "dependencies": { - "@sentry/core": "8.45.0", - "@sentry/node": "8.45.0", - "@sentry/opentelemetry": "8.45.0", - "@sentry/solid": "8.45.0", + "@sentry/core": "8.45.1", + "@sentry/node": "8.45.1", + "@sentry/opentelemetry": "8.45.1", + "@sentry/solid": "8.45.1", "@sentry/vite-plugin": "2.22.6" }, "devDependencies": { diff --git a/packages/svelte/package.json b/packages/svelte/package.json index fb95251cf35b..c701dd54704c 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/svelte", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for Svelte", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/svelte", @@ -39,8 +39,8 @@ "access": "public" }, "dependencies": { - "@sentry/browser": "8.45.0", - "@sentry/core": "8.45.0", + "@sentry/browser": "8.45.1", + "@sentry/core": "8.45.1", "magic-string": "^0.30.0" }, "peerDependencies": { diff --git a/packages/sveltekit/package.json b/packages/sveltekit/package.json index 7ae146015a74..3ea19028f0dd 100644 --- a/packages/sveltekit/package.json +++ b/packages/sveltekit/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/sveltekit", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for SvelteKit", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/sveltekit", @@ -40,10 +40,10 @@ } }, "dependencies": { - "@sentry/core": "8.45.0", - "@sentry/node": "8.45.0", - "@sentry/opentelemetry": "8.45.0", - "@sentry/svelte": "8.45.0", + "@sentry/core": "8.45.1", + "@sentry/node": "8.45.1", + "@sentry/opentelemetry": "8.45.1", + "@sentry/svelte": "8.45.1", "@sentry/vite-plugin": "2.22.6", "magic-string": "0.30.7", "magicast": "0.2.8", diff --git a/packages/types/package.json b/packages/types/package.json index 26927c6882b9..7ffd2442d6a0 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/types", - "version": "8.45.0", + "version": "8.45.1", "description": "Types for all Sentry JavaScript SDKs", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/types", @@ -56,7 +56,7 @@ "yalc:publish": "yalc publish --push --sig" }, "dependencies": { - "@sentry/core": "8.45.0" + "@sentry/core": "8.45.1" }, "volta": { "extends": "../../package.json" diff --git a/packages/typescript/package.json b/packages/typescript/package.json index 9d11789736f3..fb55b1f06894 100644 --- a/packages/typescript/package.json +++ b/packages/typescript/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/typescript", - "version": "8.45.0", + "version": "8.45.1", "description": "Typescript configuration used at Sentry", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/typescript", diff --git a/packages/utils/package.json b/packages/utils/package.json index b35f0087434b..bf29cea0aa9a 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/utils", - "version": "8.45.0", + "version": "8.45.1", "description": "Utilities for all Sentry JavaScript SDKs", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/utils", @@ -39,7 +39,7 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.45.0" + "@sentry/core": "8.45.1" }, "scripts": { "build": "run-p build:transpile build:types", diff --git a/packages/vercel-edge/package.json b/packages/vercel-edge/package.json index 4e7f81e055af..5fc79e8a19d9 100644 --- a/packages/vercel-edge/package.json +++ b/packages/vercel-edge/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/vercel-edge", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for the Vercel Edge Runtime", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/vercel-edge", @@ -40,7 +40,7 @@ }, "dependencies": { "@opentelemetry/api": "^1.9.0", - "@sentry/core": "8.45.0" + "@sentry/core": "8.45.1" }, "devDependencies": { "@edge-runtime/types": "3.0.1", @@ -48,7 +48,7 @@ "@opentelemetry/resources": "^1.29.0", "@opentelemetry/sdk-trace-base": "^1.29.0", "@opentelemetry/semantic-conventions": "^1.28.0", - "@sentry/opentelemetry": "8.45.0" + "@sentry/opentelemetry": "8.45.1" }, "scripts": { "build": "run-p build:transpile build:types", diff --git a/packages/vue/package.json b/packages/vue/package.json index 167352a6289b..83b4a4e9af2f 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/vue", - "version": "8.45.0", + "version": "8.45.1", "description": "Official Sentry SDK for Vue.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/vue", @@ -39,8 +39,8 @@ "access": "public" }, "dependencies": { - "@sentry/browser": "8.45.0", - "@sentry/core": "8.45.0" + "@sentry/browser": "8.45.1", + "@sentry/core": "8.45.1" }, "peerDependencies": { "pinia": "2.x", diff --git a/packages/wasm/package.json b/packages/wasm/package.json index a45a87130c7c..464f4fde7bb5 100644 --- a/packages/wasm/package.json +++ b/packages/wasm/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/wasm", - "version": "8.45.0", + "version": "8.45.1", "description": "Support for WASM.", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/wasm", @@ -39,8 +39,8 @@ "access": "public" }, "dependencies": { - "@sentry/browser": "8.45.0", - "@sentry/core": "8.45.0" + "@sentry/browser": "8.45.1", + "@sentry/core": "8.45.1" }, "scripts": { "build": "run-p build:transpile build:bundle build:types", From 85952db8d28f1a03e80ca16bd364dab5946db007 Mon Sep 17 00:00:00 2001 From: Andrei <168741329+andreiborza@users.noreply.github.com> Date: Mon, 16 Dec 2024 14:56:25 +0100 Subject: [PATCH 04/66] chore(craft): Publish only aws v8 layer (#14703) The v8 branch should not publish to the latest layer. --- .craft.yml | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/.craft.yml b/.craft.yml index 44d245311312..ec096880c0d6 100644 --- a/.craft.yml +++ b/.craft.yml @@ -142,7 +142,6 @@ targets: id: '@sentry-internal/eslint-config-sdk' includeNames: /^sentry-internal-eslint-config-sdk-\d.*\.tgz$/ - # TODO(v9): Remove this target # NOTE: We publish the v8 layer under its own name so people on v8 can still get patches # whenever we release a new v8 version—otherwise we would overwrite the current major lambda layer. - name: aws-lambda-layer @@ -159,21 +158,6 @@ targets: - nodejs20.x license: MIT - # AWS Lambda Layer target - - name: aws-lambda-layer - includeNames: /^sentry-node-serverless-\d+.\d+.\d+(-(beta|alpha|rc)\.\d+)?\.zip$/ - layerName: SentryNodeServerlessSDK - compatibleRuntimes: - - name: node - versions: - - nodejs10.x - - nodejs12.x - - nodejs14.x - - nodejs16.x - - nodejs18.x - - nodejs20.x - license: MIT - # CDN Bundle Target - name: gcs id: 'browser-cdn-bundles' From c698ad921d531e9b65e5ec0c383635cc4b18b737 Mon Sep 17 00:00:00 2001 From: Tim Fish Date: Mon, 16 Dec 2024 15:24:45 +0100 Subject: [PATCH 05/66] feat: Allow capture of more than 1 ANR event [v8] (#14713) --- .../suites/anr/basic-multiple.mjs | 36 +++++++++++++++++++ .../suites/anr/basic.mjs | 5 +++ .../node-integration-tests/suites/anr/test.ts | 10 +++++- packages/node/src/integrations/anr/common.ts | 6 ++++ packages/node/src/integrations/anr/index.ts | 1 + packages/node/src/integrations/anr/worker.ts | 18 +++++----- 6 files changed, 67 insertions(+), 9 deletions(-) create mode 100644 dev-packages/node-integration-tests/suites/anr/basic-multiple.mjs diff --git a/dev-packages/node-integration-tests/suites/anr/basic-multiple.mjs b/dev-packages/node-integration-tests/suites/anr/basic-multiple.mjs new file mode 100644 index 000000000000..f58eb87f8237 --- /dev/null +++ b/dev-packages/node-integration-tests/suites/anr/basic-multiple.mjs @@ -0,0 +1,36 @@ +import * as assert from 'assert'; +import * as crypto from 'crypto'; + +import * as Sentry from '@sentry/node'; + +global._sentryDebugIds = { [new Error().stack]: 'aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaa' }; + +setTimeout(() => { + process.exit(); +}, 10000); + +Sentry.init({ + dsn: process.env.SENTRY_DSN, + release: '1.0', + autoSessionTracking: false, + integrations: [Sentry.anrIntegration({ captureStackTrace: true, anrThreshold: 100, maxAnrEvents: 2 })], +}); + +Sentry.setUser({ email: 'person@home.com' }); +Sentry.addBreadcrumb({ message: 'important message!' }); + +function longWork() { + for (let i = 0; i < 20; i++) { + const salt = crypto.randomBytes(128).toString('base64'); + const hash = crypto.pbkdf2Sync('myPassword', salt, 10000, 512, 'sha512'); + assert.ok(hash); + } +} + +setTimeout(() => { + longWork(); +}, 1000); + +setTimeout(() => { + longWork(); +}, 4000); diff --git a/dev-packages/node-integration-tests/suites/anr/basic.mjs b/dev-packages/node-integration-tests/suites/anr/basic.mjs index 18777e5ecdbd..454a35605925 100644 --- a/dev-packages/node-integration-tests/suites/anr/basic.mjs +++ b/dev-packages/node-integration-tests/suites/anr/basic.mjs @@ -30,3 +30,8 @@ function longWork() { setTimeout(() => { longWork(); }, 1000); + +// Ensure we only send one event even with multiple blocking events +setTimeout(() => { + longWork(); +}, 4000); diff --git a/dev-packages/node-integration-tests/suites/anr/test.ts b/dev-packages/node-integration-tests/suites/anr/test.ts index b1750b308d28..d1d9c684bf60 100644 --- a/dev-packages/node-integration-tests/suites/anr/test.ts +++ b/dev-packages/node-integration-tests/suites/anr/test.ts @@ -101,7 +101,7 @@ const ANR_EVENT_WITH_DEBUG_META: Event = { { type: 'sourcemap', debug_id: 'aaaaaaaa-aaaa-4aaa-aaaa-aaaaaaaaaa', - code_file: expect.stringContaining('basic.'), + code_file: expect.stringContaining('basic'), }, ], }, @@ -123,6 +123,14 @@ conditionalTest({ min: 16 })('should report ANR when event loop blocked', () => .start(done); }); + test('multiple events via maxAnrEvents', done => { + createRunner(__dirname, 'basic-multiple.mjs') + .withMockSentryServer() + .expect({ event: ANR_EVENT_WITH_DEBUG_META }) + .expect({ event: ANR_EVENT_WITH_DEBUG_META }) + .start(done); + }); + test('blocked indefinitely', done => { createRunner(__dirname, 'indefinite.mjs').withMockSentryServer().expect({ event: ANR_EVENT }).start(done); }); diff --git a/packages/node/src/integrations/anr/common.ts b/packages/node/src/integrations/anr/common.ts index e2666e3ecd3e..fc1b23e35b1d 100644 --- a/packages/node/src/integrations/anr/common.ts +++ b/packages/node/src/integrations/anr/common.ts @@ -21,6 +21,12 @@ export interface AnrIntegrationOptions { * This uses the node debugger which enables the inspector API and opens the required ports. */ captureStackTrace: boolean; + /** + * Maximum number of ANR events to send. + * + * Defaults to 1. + */ + maxAnrEvents: number; /** * Tags to include with ANR events. */ diff --git a/packages/node/src/integrations/anr/index.ts b/packages/node/src/integrations/anr/index.ts index f0cef4d60831..b71bdfa49c52 100644 --- a/packages/node/src/integrations/anr/index.ts +++ b/packages/node/src/integrations/anr/index.ts @@ -160,6 +160,7 @@ async function _startWorker( pollInterval: integrationOptions.pollInterval || DEFAULT_INTERVAL, anrThreshold: integrationOptions.anrThreshold || DEFAULT_HANG_THRESHOLD, captureStackTrace: !!integrationOptions.captureStackTrace, + maxAnrEvents: integrationOptions.maxAnrEvents || 1, staticTags: integrationOptions.staticTags || {}, contexts, }; diff --git a/packages/node/src/integrations/anr/worker.ts b/packages/node/src/integrations/anr/worker.ts index 354cea514618..a1ad39294c3e 100644 --- a/packages/node/src/integrations/anr/worker.ts +++ b/packages/node/src/integrations/anr/worker.ts @@ -23,7 +23,7 @@ type VoidFunction = () => void; const options: WorkerStartData = workerData; let session: Session | undefined; -let hasSentAnrEvent = false; +let sentAnrEvents = 0; let mainDebugImages: Record = {}; function log(msg: string): void { @@ -134,11 +134,11 @@ function applyScopeToEvent(event: Event, scope: ScopeData): void { } async function sendAnrEvent(frames?: StackFrame[], scope?: ScopeData): Promise { - if (hasSentAnrEvent) { + if (sentAnrEvents >= options.maxAnrEvents) { return; } - hasSentAnrEvent = true; + sentAnrEvents += 1; await sendAbnormalSession(); @@ -179,11 +179,13 @@ async function sendAnrEvent(frames?: StackFrame[], scope?: ScopeData): Promise { - process.exit(0); - }, 5_000); + if (sentAnrEvents >= options.maxAnrEvents) { + // Delay for 5 seconds so that stdio can flush if the main event loop ever restarts. + // This is mainly for the benefit of logging or debugging. + setTimeout(() => { + process.exit(0); + }, 5_000); + } } let debuggerPause: VoidFunction | undefined; From 6e682c46092105783b756e27774429ac3c6f8e05 Mon Sep 17 00:00:00 2001 From: Tim Fish Date: Mon, 16 Dec 2024 16:57:26 +0100 Subject: [PATCH 06/66] fix: Normalise ANR debug image file paths if appRoot was supplied [v8] (#14709) We should normalise all paths in ANR events if an appRoot path is supplied. This is important for the Electron SDK where we normalise around the app path to keep usernames out of reported events. Co-authored-by: Abhijeet Prasad --- packages/node/src/integrations/anr/worker.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/node/src/integrations/anr/worker.ts b/packages/node/src/integrations/anr/worker.ts index a1ad39294c3e..f412806b1117 100644 --- a/packages/node/src/integrations/anr/worker.ts +++ b/packages/node/src/integrations/anr/worker.ts @@ -104,11 +104,13 @@ function applyDebugMeta(event: Event): void { if (filenameToDebugId.size > 0) { const images: DebugImage[] = []; - for (const [filename, debugId] of filenameToDebugId.entries()) { + for (const [filename, debug_id] of filenameToDebugId.entries()) { + const code_file = options.appRootPath ? normalizeUrlToBase(filename, options.appRootPath) : filename; + images.push({ type: 'sourcemap', - code_file: filename, - debug_id: debugId, + code_file, + debug_id, }); } event.debug_meta = { images }; From 9527563769d078c1761e649bad8b68e7b2f68ccb Mon Sep 17 00:00:00 2001 From: Abhijeet Prasad Date: Mon, 16 Dec 2024 10:57:44 -0500 Subject: [PATCH 07/66] feat(node): Detect Railway release name [v8] (#14714) Co-authored-by: Conor O'Brien --- CHANGELOG.md | 2 ++ packages/node/src/sdk/api.ts | 2 ++ packages/vercel-edge/src/sdk.ts | 2 ++ 3 files changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3f0e52db2e6..810e75fee33b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ - "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott +Work in this release was contributed by @conor-ob. Thank you for your contribution! + ## 8.45.1 - fix(feedback): Return when the `sendFeedback` promise resolves ([#14683](https://github.com/getsentry/sentry-javascript/pull/14683)) diff --git a/packages/node/src/sdk/api.ts b/packages/node/src/sdk/api.ts index dd7ccc8ca75d..7e4f200d1e06 100644 --- a/packages/node/src/sdk/api.ts +++ b/packages/node/src/sdk/api.ts @@ -68,6 +68,8 @@ export function getSentryRelease(fallback?: string): string | undefined { process.env['HEROKU_TEST_RUN_COMMIT_VERSION'] || // Heroku #2 https://docs.sentry.io/product/integrations/deployment/heroku/#configure-releases process.env['HEROKU_SLUG_COMMIT'] || + // Railway - https://docs.railway.app/reference/variables#git-variables + process.env['RAILWAY_GIT_COMMIT_SHA'] || // Render - https://render.com/docs/environment-variables process.env['RENDER_GIT_COMMIT'] || // Semaphore CI - https://docs.semaphoreci.com/ci-cd-environment/environment-variables diff --git a/packages/vercel-edge/src/sdk.ts b/packages/vercel-edge/src/sdk.ts index 78f1f49ba092..c29e9f693ba2 100644 --- a/packages/vercel-edge/src/sdk.ts +++ b/packages/vercel-edge/src/sdk.ts @@ -268,6 +268,8 @@ export function getSentryRelease(fallback?: string): string | undefined { process.env['HEROKU_TEST_RUN_COMMIT_VERSION'] || // Heroku #2 https://docs.sentry.io/product/integrations/deployment/heroku/#configure-releases process.env['HEROKU_SLUG_COMMIT'] || + // Railway - https://docs.railway.app/reference/variables#git-variables + process.env['RAILWAY_GIT_COMMIT_SHA'] || // Render - https://render.com/docs/environment-variables process.env['RENDER_GIT_COMMIT'] || // Semaphore CI - https://docs.semaphoreci.com/ci-cd-environment/environment-variables From d32bf15a0d4e499cf7d0d8e27adee35b99743f1a Mon Sep 17 00:00:00 2001 From: Sigrid Huemer <32902192+s1gr1d@users.noreply.github.com> Date: Mon, 16 Dec 2024 17:23:23 +0100 Subject: [PATCH 08/66] fix(nuxt): Remove build config from tsconfig (#14737) backport https://github.com/getsentry/sentry-javascript/pull/14735 fixes https://github.com/getsentry/sentry-javascript/issues/14732 --- packages/nuxt/tsconfig.types.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nuxt/tsconfig.types.json b/packages/nuxt/tsconfig.types.json index 65455f66bd75..cab81135cd7a 100644 --- a/packages/nuxt/tsconfig.types.json +++ b/packages/nuxt/tsconfig.types.json @@ -1,6 +1,6 @@ { "extends": "./tsconfig.json", - + "exclude": ["build.config.ts"], "compilerOptions": { "declaration": true, "declarationMap": true, From dcc5742bf169151055d35b5daa8b07a02cab83c9 Mon Sep 17 00:00:00 2001 From: Andrew Liu <159852527+aliu39@users.noreply.github.com> Date: Mon, 16 Dec 2024 11:09:31 -0800 Subject: [PATCH 09/66] ref(flags): don't export FeatureFlagContext in types-hoist/context.ts (#14741) This isn't exported in types-hoist/index, but we found users can still import it from a `build/` file. Discussed with @billyvg we don't want users to accidentally import it this way. Note we currently use this type in sentry, until https://github.com/getsentry/sentry/pull/81954 is rolled out. --- packages/core/src/types-hoist/context.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/core/src/types-hoist/context.ts b/packages/core/src/types-hoist/context.ts index 60aa60b38868..ad6879636086 100644 --- a/packages/core/src/types-hoist/context.ts +++ b/packages/core/src/types-hoist/context.ts @@ -133,6 +133,6 @@ export interface MissingInstrumentationContext extends Record { * directly is not recommended. Use the functions in @sentry/browser * src/utils/featureFlags instead. */ -export interface FeatureFlagContext extends Record { +interface FeatureFlagContext extends Record { values: FeatureFlag[]; } From 0e5e77a80a46ade86bf39ff8d152a8a53402b480 Mon Sep 17 00:00:00 2001 From: s1gr1d Date: Mon, 16 Dec 2024 17:31:08 +0100 Subject: [PATCH 10/66] meta(changelog): Update changelog for 8.46.0 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 810e75fee33b..bb7a3f2421e9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,13 @@ - "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott +## 8.46.0 + +- feat: Allow capture of more than 1 ANR event [v8] ([#14713](https://github.com/getsentry/sentry-javascript/pull/14713)) +- feat(node): Detect Railway release name [v8] ([#14714](https://github.com/getsentry/sentry-javascript/pull/14714)) +- fix: Normalise ANR debug image file paths if appRoot was supplied [v8] ([#14709](https://github.com/getsentry/sentry-javascript/pull/14709)) +- fix(nuxt): Remove build config from tsconfig ([#14737](https://github.com/getsentry/sentry-javascript/pull/14737)) + Work in this release was contributed by @conor-ob. Thank you for your contribution! ## 8.45.1 From 5387fdefe4181235d39baef0786fc1712d00d810 Mon Sep 17 00:00:00 2001 From: getsentry-bot Date: Tue, 17 Dec 2024 09:30:07 +0000 Subject: [PATCH 11/66] release: 8.46.0 --- .../browser-integration-tests/package.json | 4 ++-- .../bundle-analyzer-scenarios/package.json | 2 +- dev-packages/clear-cache-gh-action/package.json | 2 +- dev-packages/e2e-tests/package.json | 2 +- .../external-contributor-gh-action/package.json | 2 +- dev-packages/node-integration-tests/package.json | 8 ++++---- dev-packages/rollup-utils/package.json | 2 +- dev-packages/size-limit-gh-action/package.json | 2 +- dev-packages/test-utils/package.json | 4 ++-- lerna.json | 2 +- packages/angular/package.json | 6 +++--- packages/astro/package.json | 8 ++++---- packages/aws-serverless/package.json | 6 +++--- packages/browser-utils/package.json | 4 ++-- packages/browser/package.json | 14 +++++++------- packages/bun/package.json | 8 ++++---- packages/cloudflare/package.json | 4 ++-- packages/core/package.json | 2 +- packages/deno/package.json | 4 ++-- packages/ember/package.json | 6 +++--- packages/eslint-config-sdk/package.json | 6 +++--- packages/eslint-plugin-sdk/package.json | 2 +- packages/feedback/package.json | 4 ++-- packages/gatsby/package.json | 6 +++--- packages/google-cloud-serverless/package.json | 6 +++--- packages/integration-shims/package.json | 4 ++-- packages/nestjs/package.json | 6 +++--- packages/nextjs/package.json | 14 +++++++------- packages/nitro-utils/package.json | 4 ++-- packages/node/package.json | 6 +++--- packages/nuxt/package.json | 12 ++++++------ packages/opentelemetry/package.json | 4 ++-- packages/profiling-node/package.json | 6 +++--- packages/react/package.json | 6 +++--- packages/remix/package.json | 10 +++++----- packages/replay-canvas/package.json | 6 +++--- packages/replay-internal/package.json | 8 ++++---- packages/replay-worker/package.json | 2 +- packages/solid/package.json | 6 +++--- packages/solidstart/package.json | 10 +++++----- packages/svelte/package.json | 6 +++--- packages/sveltekit/package.json | 10 +++++----- packages/types/package.json | 4 ++-- packages/typescript/package.json | 2 +- packages/utils/package.json | 4 ++-- packages/vercel-edge/package.json | 6 +++--- packages/vue/package.json | 6 +++--- packages/wasm/package.json | 6 +++--- 48 files changed, 132 insertions(+), 132 deletions(-) diff --git a/dev-packages/browser-integration-tests/package.json b/dev-packages/browser-integration-tests/package.json index 20ea83b4b210..d168beb19230 100644 --- a/dev-packages/browser-integration-tests/package.json +++ b/dev-packages/browser-integration-tests/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/browser-integration-tests", - "version": "8.45.1", + "version": "8.46.0", "main": "index.js", "license": "MIT", "engines": { @@ -43,7 +43,7 @@ "@babel/preset-typescript": "^7.16.7", "@playwright/test": "^1.44.1", "@sentry-internal/rrweb": "2.31.0", - "@sentry/browser": "8.45.1", + "@sentry/browser": "8.46.0", "axios": "1.7.7", "babel-loader": "^8.2.2", "html-webpack-plugin": "^5.5.0", diff --git a/dev-packages/bundle-analyzer-scenarios/package.json b/dev-packages/bundle-analyzer-scenarios/package.json index 7c2b0f0dfdc4..f30816811b2e 100644 --- a/dev-packages/bundle-analyzer-scenarios/package.json +++ b/dev-packages/bundle-analyzer-scenarios/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/bundle-analyzer-scenarios", - "version": "8.45.1", + "version": "8.46.0", "description": "Scenarios to test bundle analysis with", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/dev-packages/bundle-analyzer-scenarios", diff --git a/dev-packages/clear-cache-gh-action/package.json b/dev-packages/clear-cache-gh-action/package.json index 7e624b474216..665a4eff0d64 100644 --- a/dev-packages/clear-cache-gh-action/package.json +++ b/dev-packages/clear-cache-gh-action/package.json @@ -1,7 +1,7 @@ { "name": "@sentry-internal/clear-cache-gh-action", "description": "An internal Github Action to clear GitHub caches.", - "version": "8.45.1", + "version": "8.46.0", "license": "MIT", "engines": { "node": ">=18" diff --git a/dev-packages/e2e-tests/package.json b/dev-packages/e2e-tests/package.json index 2f0f686f2179..dfb741564e2b 100644 --- a/dev-packages/e2e-tests/package.json +++ b/dev-packages/e2e-tests/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/e2e-tests", - "version": "8.45.1", + "version": "8.46.0", "license": "MIT", "private": true, "scripts": { diff --git a/dev-packages/external-contributor-gh-action/package.json b/dev-packages/external-contributor-gh-action/package.json index 6831ccd89718..b941a84f894e 100644 --- a/dev-packages/external-contributor-gh-action/package.json +++ b/dev-packages/external-contributor-gh-action/package.json @@ -1,7 +1,7 @@ { "name": "@sentry-internal/external-contributor-gh-action", "description": "An internal Github Action to add external contributors to the CHANGELOG.md file.", - "version": "8.45.1", + "version": "8.46.0", "license": "MIT", "engines": { "node": ">=18" diff --git a/dev-packages/node-integration-tests/package.json b/dev-packages/node-integration-tests/package.json index 8c52cfbb03be..53d35656a5c2 100644 --- a/dev-packages/node-integration-tests/package.json +++ b/dev-packages/node-integration-tests/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/node-integration-tests", - "version": "8.45.1", + "version": "8.46.0", "license": "MIT", "engines": { "node": ">=14.18" @@ -31,9 +31,9 @@ "@nestjs/core": "10.4.6", "@nestjs/platform-express": "10.4.6", "@prisma/client": "5.9.1", - "@sentry/aws-serverless": "8.45.1", - "@sentry/core": "8.45.1", - "@sentry/node": "8.45.1", + "@sentry/aws-serverless": "8.46.0", + "@sentry/core": "8.46.0", + "@sentry/node": "8.46.0", "@types/mongodb": "^3.6.20", "@types/mysql": "^2.15.21", "@types/pg": "^8.6.5", diff --git a/dev-packages/rollup-utils/package.json b/dev-packages/rollup-utils/package.json index 36d8b82c5457..7f3b622336bb 100644 --- a/dev-packages/rollup-utils/package.json +++ b/dev-packages/rollup-utils/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/rollup-utils", - "version": "8.45.1", + "version": "8.46.0", "description": "Rollup utilities used at Sentry for the Sentry JavaScript SDK", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/rollup-utils", diff --git a/dev-packages/size-limit-gh-action/package.json b/dev-packages/size-limit-gh-action/package.json index 01555aff7e3f..e37db5256ba7 100644 --- a/dev-packages/size-limit-gh-action/package.json +++ b/dev-packages/size-limit-gh-action/package.json @@ -1,7 +1,7 @@ { "name": "@sentry-internal/size-limit-gh-action", "description": "An internal Github Action to compare the current size of a PR against the one on develop.", - "version": "8.45.1", + "version": "8.46.0", "license": "MIT", "engines": { "node": ">=18" diff --git a/dev-packages/test-utils/package.json b/dev-packages/test-utils/package.json index 6d5bb7e0f073..5497d41bded2 100644 --- a/dev-packages/test-utils/package.json +++ b/dev-packages/test-utils/package.json @@ -1,6 +1,6 @@ { "private": true, - "version": "8.45.1", + "version": "8.46.0", "name": "@sentry-internal/test-utils", "author": "Sentry", "license": "MIT", @@ -45,7 +45,7 @@ }, "devDependencies": { "@playwright/test": "^1.44.1", - "@sentry/core": "8.45.1" + "@sentry/core": "8.46.0" }, "volta": { "extends": "../../package.json" diff --git a/lerna.json b/lerna.json index d1d73317d6a6..ec70f1c52fe5 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { "$schema": "node_modules/lerna/schemas/lerna-schema.json", - "version": "8.45.1", + "version": "8.46.0", "npmClient": "yarn" } diff --git a/packages/angular/package.json b/packages/angular/package.json index 4c7b6c2e996c..c0e3d0a2bff8 100644 --- a/packages/angular/package.json +++ b/packages/angular/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/angular", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for Angular", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/angular", @@ -21,8 +21,8 @@ "rxjs": "^6.5.5 || ^7.x" }, "dependencies": { - "@sentry/browser": "8.45.1", - "@sentry/core": "8.45.1", + "@sentry/browser": "8.46.0", + "@sentry/core": "8.46.0", "tslib": "^2.4.1" }, "devDependencies": { diff --git a/packages/astro/package.json b/packages/astro/package.json index 3d8ff8bd75c4..79aa57646fc0 100644 --- a/packages/astro/package.json +++ b/packages/astro/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/astro", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for Astro", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/astro", @@ -56,9 +56,9 @@ "astro": ">=3.x || >=4.0.0-beta || >=5.x" }, "dependencies": { - "@sentry/browser": "8.45.1", - "@sentry/core": "8.45.1", - "@sentry/node": "8.45.1", + "@sentry/browser": "8.46.0", + "@sentry/core": "8.46.0", + "@sentry/node": "8.46.0", "@sentry/vite-plugin": "^2.22.6" }, "devDependencies": { diff --git a/packages/aws-serverless/package.json b/packages/aws-serverless/package.json index 92a2fe02eb36..ba1d0327cb2e 100644 --- a/packages/aws-serverless/package.json +++ b/packages/aws-serverless/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/aws-serverless", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for AWS Lambda and AWS Serverless Environments", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/serverless", @@ -68,8 +68,8 @@ "@opentelemetry/instrumentation": "^0.56.0", "@opentelemetry/instrumentation-aws-lambda": "0.49.0", "@opentelemetry/instrumentation-aws-sdk": "0.48.0", - "@sentry/core": "8.45.1", - "@sentry/node": "8.45.1", + "@sentry/core": "8.46.0", + "@sentry/node": "8.46.0", "@types/aws-lambda": "^8.10.62" }, "devDependencies": { diff --git a/packages/browser-utils/package.json b/packages/browser-utils/package.json index a85449e7ea1a..f49ca44549e4 100644 --- a/packages/browser-utils/package.json +++ b/packages/browser-utils/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/browser-utils", - "version": "8.45.1", + "version": "8.46.0", "description": "Browser Utilities for all Sentry JavaScript SDKs", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/browser-utils", @@ -39,7 +39,7 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.45.1" + "@sentry/core": "8.46.0" }, "scripts": { "build": "run-p build:transpile build:types", diff --git a/packages/browser/package.json b/packages/browser/package.json index 371533f5f84e..a3d55a7a1de5 100644 --- a/packages/browser/package.json +++ b/packages/browser/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/browser", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for browsers", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/browser", @@ -39,14 +39,14 @@ "access": "public" }, "dependencies": { - "@sentry-internal/browser-utils": "8.45.1", - "@sentry-internal/feedback": "8.45.1", - "@sentry-internal/replay": "8.45.1", - "@sentry-internal/replay-canvas": "8.45.1", - "@sentry/core": "8.45.1" + "@sentry-internal/browser-utils": "8.46.0", + "@sentry-internal/feedback": "8.46.0", + "@sentry-internal/replay": "8.46.0", + "@sentry-internal/replay-canvas": "8.46.0", + "@sentry/core": "8.46.0" }, "devDependencies": { - "@sentry-internal/integration-shims": "8.45.1", + "@sentry-internal/integration-shims": "8.46.0", "fake-indexeddb": "^4.0.1" }, "scripts": { diff --git a/packages/bun/package.json b/packages/bun/package.json index d88bd81a68d4..e6582f21aacb 100644 --- a/packages/bun/package.json +++ b/packages/bun/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/bun", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for bun", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/bun", @@ -39,9 +39,9 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.45.1", - "@sentry/node": "8.45.1", - "@sentry/opentelemetry": "8.45.1" + "@sentry/core": "8.46.0", + "@sentry/node": "8.46.0", + "@sentry/opentelemetry": "8.46.0" }, "devDependencies": { "bun-types": "latest" diff --git a/packages/cloudflare/package.json b/packages/cloudflare/package.json index 7281d39677a3..589bca09ac6a 100644 --- a/packages/cloudflare/package.json +++ b/packages/cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/cloudflare", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for Cloudflare Workers and Pages", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/cloudflare", @@ -39,7 +39,7 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.45.1" + "@sentry/core": "8.46.0" }, "optionalDependencies": { "@cloudflare/workers-types": "^4.x" diff --git a/packages/core/package.json b/packages/core/package.json index 852e15913fc3..dc59dbe46206 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/core", - "version": "8.45.1", + "version": "8.46.0", "description": "Base implementation for all Sentry JavaScript SDKs", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/core", diff --git a/packages/deno/package.json b/packages/deno/package.json index 19a8d2cbfc00..a1180679fe52 100644 --- a/packages/deno/package.json +++ b/packages/deno/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/deno", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for Deno", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/deno", @@ -24,7 +24,7 @@ "/build" ], "dependencies": { - "@sentry/core": "8.45.1" + "@sentry/core": "8.46.0" }, "devDependencies": { "@rollup/plugin-typescript": "^11.1.5", diff --git a/packages/ember/package.json b/packages/ember/package.json index 25adb5a21692..966bea99bbe1 100644 --- a/packages/ember/package.json +++ b/packages/ember/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/ember", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for Ember.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/ember", @@ -32,8 +32,8 @@ "dependencies": { "@babel/core": "^7.24.4", "@embroider/macros": "^1.16.0", - "@sentry/browser": "8.45.1", - "@sentry/core": "8.45.1", + "@sentry/browser": "8.46.0", + "@sentry/core": "8.46.0", "ember-auto-import": "^2.7.2", "ember-cli-babel": "^8.2.0", "ember-cli-htmlbars": "^6.1.1", diff --git a/packages/eslint-config-sdk/package.json b/packages/eslint-config-sdk/package.json index cc8568825bea..7c53e7ed37cc 100644 --- a/packages/eslint-config-sdk/package.json +++ b/packages/eslint-config-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/eslint-config-sdk", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK eslint config", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/eslint-config-sdk", @@ -22,8 +22,8 @@ "access": "public" }, "dependencies": { - "@sentry-internal/eslint-plugin-sdk": "8.45.1", - "@sentry-internal/typescript": "8.45.1", + "@sentry-internal/eslint-plugin-sdk": "8.46.0", + "@sentry-internal/typescript": "8.46.0", "@typescript-eslint/eslint-plugin": "^5.48.0", "@typescript-eslint/parser": "^5.48.0", "eslint-config-prettier": "^6.11.0", diff --git a/packages/eslint-plugin-sdk/package.json b/packages/eslint-plugin-sdk/package.json index aa7360ae1d21..742049094389 100644 --- a/packages/eslint-plugin-sdk/package.json +++ b/packages/eslint-plugin-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/eslint-plugin-sdk", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK eslint plugin", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/eslint-plugin-sdk", diff --git a/packages/feedback/package.json b/packages/feedback/package.json index 2d0f76b55038..860ce80b31ca 100644 --- a/packages/feedback/package.json +++ b/packages/feedback/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/feedback", - "version": "8.45.1", + "version": "8.46.0", "description": "Sentry SDK integration for user feedback", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/feedback", @@ -39,7 +39,7 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.45.1" + "@sentry/core": "8.46.0" }, "devDependencies": { "preact": "^10.19.4" diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index 8645462f1492..aac5cd78ca8b 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/gatsby", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for Gatsby.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/gatsby", @@ -45,8 +45,8 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.45.1", - "@sentry/react": "8.45.1", + "@sentry/core": "8.46.0", + "@sentry/react": "8.46.0", "@sentry/webpack-plugin": "2.22.7" }, "peerDependencies": { diff --git a/packages/google-cloud-serverless/package.json b/packages/google-cloud-serverless/package.json index f23b69985aa6..19c15017d3da 100644 --- a/packages/google-cloud-serverless/package.json +++ b/packages/google-cloud-serverless/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/google-cloud-serverless", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for Google Cloud Functions", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/google-cloud-serverless", @@ -48,8 +48,8 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.45.1", - "@sentry/node": "8.45.1", + "@sentry/core": "8.46.0", + "@sentry/node": "8.46.0", "@types/express": "^4.17.14" }, "devDependencies": { diff --git a/packages/integration-shims/package.json b/packages/integration-shims/package.json index 091770cb3bed..e97f45c502d1 100644 --- a/packages/integration-shims/package.json +++ b/packages/integration-shims/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/integration-shims", - "version": "8.45.1", + "version": "8.46.0", "description": "Shims for integrations in Sentry SDK.", "main": "build/cjs/index.js", "module": "build/esm/index.js", @@ -55,7 +55,7 @@ "url": "https://github.com/getsentry/sentry-javascript/issues" }, "dependencies": { - "@sentry/core": "8.45.1" + "@sentry/core": "8.46.0" }, "engines": { "node": ">=14.18" diff --git a/packages/nestjs/package.json b/packages/nestjs/package.json index b266bd65a836..269b5674ab57 100644 --- a/packages/nestjs/package.json +++ b/packages/nestjs/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/nestjs", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for NestJS", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/nestjs", @@ -44,8 +44,8 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.45.1", - "@sentry/node": "8.45.1" + "@sentry/core": "8.46.0", + "@sentry/node": "8.46.0" }, "devDependencies": { "@nestjs/common": "^8.0.0 || ^9.0.0 || ^10.0.0", diff --git a/packages/nextjs/package.json b/packages/nextjs/package.json index 335371c7a827..095b65246f25 100644 --- a/packages/nextjs/package.json +++ b/packages/nextjs/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/nextjs", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for Next.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/nextjs", @@ -79,12 +79,12 @@ "@opentelemetry/api": "^1.9.0", "@opentelemetry/semantic-conventions": "^1.28.0", "@rollup/plugin-commonjs": "28.0.1", - "@sentry-internal/browser-utils": "8.45.1", - "@sentry/core": "8.45.1", - "@sentry/node": "8.45.1", - "@sentry/opentelemetry": "8.45.1", - "@sentry/react": "8.45.1", - "@sentry/vercel-edge": "8.45.1", + "@sentry-internal/browser-utils": "8.46.0", + "@sentry/core": "8.46.0", + "@sentry/node": "8.46.0", + "@sentry/opentelemetry": "8.46.0", + "@sentry/react": "8.46.0", + "@sentry/vercel-edge": "8.46.0", "@sentry/webpack-plugin": "2.22.7", "chalk": "3.0.0", "resolve": "1.22.8", diff --git a/packages/nitro-utils/package.json b/packages/nitro-utils/package.json index 1d238b503c5c..436b6ca939d0 100644 --- a/packages/nitro-utils/package.json +++ b/packages/nitro-utils/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/nitro-utils", - "version": "8.45.1", + "version": "8.46.0", "description": "Utilities for all Sentry SDKs with Nitro on the server-side", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/nitro-utils", @@ -37,7 +37,7 @@ } }, "dependencies": { - "@sentry/core": "8.45.1" + "@sentry/core": "8.46.0" }, "devDependencies": { "rollup": "^4.24.4" diff --git a/packages/node/package.json b/packages/node/package.json index c8c9a6996adf..5f98c240269b 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/node", - "version": "8.45.1", + "version": "8.46.0", "description": "Sentry Node SDK using OpenTelemetry for performance instrumentation", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/node", @@ -97,8 +97,8 @@ "@opentelemetry/sdk-trace-base": "^1.29.0", "@opentelemetry/semantic-conventions": "^1.28.0", "@prisma/instrumentation": "5.19.1", - "@sentry/core": "8.45.1", - "@sentry/opentelemetry": "8.45.1", + "@sentry/core": "8.46.0", + "@sentry/opentelemetry": "8.46.0", "import-in-the-middle": "^1.11.2" }, "devDependencies": { diff --git a/packages/nuxt/package.json b/packages/nuxt/package.json index 714e3abbbb5a..251ff3a27e57 100644 --- a/packages/nuxt/package.json +++ b/packages/nuxt/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/nuxt", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for Nuxt (EXPERIMENTAL)", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/nuxt", @@ -43,13 +43,13 @@ }, "dependencies": { "@nuxt/kit": "^3.13.2", - "@sentry/browser": "8.45.1", - "@sentry/core": "8.45.1", - "@sentry/node": "8.45.1", - "@sentry/opentelemetry": "8.45.1", + "@sentry/browser": "8.46.0", + "@sentry/core": "8.46.0", + "@sentry/node": "8.46.0", + "@sentry/opentelemetry": "8.46.0", "@sentry/rollup-plugin": "2.22.7", "@sentry/vite-plugin": "2.22.6", - "@sentry/vue": "8.45.1" + "@sentry/vue": "8.46.0" }, "devDependencies": { "@nuxt/module-builder": "^0.8.4", diff --git a/packages/opentelemetry/package.json b/packages/opentelemetry/package.json index 3356d3728919..298634c57054 100644 --- a/packages/opentelemetry/package.json +++ b/packages/opentelemetry/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/opentelemetry", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry utilities for OpenTelemetry", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/opentelemetry", @@ -39,7 +39,7 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.45.1" + "@sentry/core": "8.46.0" }, "peerDependencies": { "@opentelemetry/api": "^1.9.0", diff --git a/packages/profiling-node/package.json b/packages/profiling-node/package.json index 349935ef762c..20a354ab9fa1 100644 --- a/packages/profiling-node/package.json +++ b/packages/profiling-node/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/profiling-node", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for Node.js Profiling", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/profiling-node", @@ -75,8 +75,8 @@ "test": "cross-env SENTRY_PROFILER_BINARY_DIR=lib jest --config jest.config.js" }, "dependencies": { - "@sentry/core": "8.45.1", - "@sentry/node": "8.45.1", + "@sentry/core": "8.46.0", + "@sentry/node": "8.46.0", "detect-libc": "^2.0.2", "node-abi": "^3.61.0" }, diff --git a/packages/react/package.json b/packages/react/package.json index e94f07db3bab..2b3804bfd93f 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/react", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for React.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/react", @@ -39,8 +39,8 @@ "access": "public" }, "dependencies": { - "@sentry/browser": "8.45.1", - "@sentry/core": "8.45.1", + "@sentry/browser": "8.46.0", + "@sentry/core": "8.46.0", "hoist-non-react-statics": "^3.3.2" }, "peerDependencies": { diff --git a/packages/remix/package.json b/packages/remix/package.json index 7374b71185ef..9f0b3bc19958 100644 --- a/packages/remix/package.json +++ b/packages/remix/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/remix", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for Remix", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/remix", @@ -55,10 +55,10 @@ "@opentelemetry/api": "^1.9.0", "@remix-run/router": "1.x", "@sentry/cli": "^2.39.1", - "@sentry/core": "8.45.1", - "@sentry/node": "8.45.1", - "@sentry/opentelemetry": "8.45.1", - "@sentry/react": "8.45.1", + "@sentry/core": "8.46.0", + "@sentry/node": "8.46.0", + "@sentry/opentelemetry": "8.46.0", + "@sentry/react": "8.46.0", "glob": "^10.3.4", "opentelemetry-instrumentation-remix": "0.8.0", "yargs": "^17.6.0" diff --git a/packages/replay-canvas/package.json b/packages/replay-canvas/package.json index 33a431309eb7..9509aeddaf8f 100644 --- a/packages/replay-canvas/package.json +++ b/packages/replay-canvas/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/replay-canvas", - "version": "8.45.1", + "version": "8.46.0", "description": "Replay canvas integration", "main": "build/npm/cjs/index.js", "module": "build/npm/esm/index.js", @@ -68,8 +68,8 @@ "@sentry-internal/rrweb": "2.31.0" }, "dependencies": { - "@sentry-internal/replay": "8.45.1", - "@sentry/core": "8.45.1" + "@sentry-internal/replay": "8.46.0", + "@sentry/core": "8.46.0" }, "engines": { "node": ">=14.18" diff --git a/packages/replay-internal/package.json b/packages/replay-internal/package.json index de8c0bde0cf1..7d604267c6a1 100644 --- a/packages/replay-internal/package.json +++ b/packages/replay-internal/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/replay", - "version": "8.45.1", + "version": "8.46.0", "description": "User replays for Sentry", "main": "build/npm/cjs/index.js", "module": "build/npm/esm/index.js", @@ -68,7 +68,7 @@ "homepage": "https://docs.sentry.io/platforms/javascript/session-replay/", "devDependencies": { "@babel/core": "^7.17.5", - "@sentry-internal/replay-worker": "8.45.1", + "@sentry-internal/replay-worker": "8.46.0", "@sentry-internal/rrweb": "2.31.0", "@sentry-internal/rrweb-snapshot": "2.31.0", "fflate": "^0.8.1", @@ -76,8 +76,8 @@ "jsdom-worker": "^0.2.1" }, "dependencies": { - "@sentry-internal/browser-utils": "8.45.1", - "@sentry/core": "8.45.1" + "@sentry-internal/browser-utils": "8.46.0", + "@sentry/core": "8.46.0" }, "engines": { "node": ">=14.18" diff --git a/packages/replay-worker/package.json b/packages/replay-worker/package.json index f134839b171c..11ea5ea156e9 100644 --- a/packages/replay-worker/package.json +++ b/packages/replay-worker/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/replay-worker", - "version": "8.45.1", + "version": "8.46.0", "description": "Worker for @sentry-internal/replay", "main": "build/esm/index.js", "module": "build/esm/index.js", diff --git a/packages/solid/package.json b/packages/solid/package.json index 93a2aeb35a91..58185b07422b 100644 --- a/packages/solid/package.json +++ b/packages/solid/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/solid", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for Solid", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/solid", @@ -44,8 +44,8 @@ "access": "public" }, "dependencies": { - "@sentry/browser": "8.45.1", - "@sentry/core": "8.45.1" + "@sentry/browser": "8.46.0", + "@sentry/core": "8.46.0" }, "peerDependencies": { "@solidjs/router": "^0.13.4", diff --git a/packages/solidstart/package.json b/packages/solidstart/package.json index 72d2ad4e37e7..44e21744fc17 100644 --- a/packages/solidstart/package.json +++ b/packages/solidstart/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/solidstart", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for Solid Start", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/solidstart", @@ -66,10 +66,10 @@ } }, "dependencies": { - "@sentry/core": "8.45.1", - "@sentry/node": "8.45.1", - "@sentry/opentelemetry": "8.45.1", - "@sentry/solid": "8.45.1", + "@sentry/core": "8.46.0", + "@sentry/node": "8.46.0", + "@sentry/opentelemetry": "8.46.0", + "@sentry/solid": "8.46.0", "@sentry/vite-plugin": "2.22.6" }, "devDependencies": { diff --git a/packages/svelte/package.json b/packages/svelte/package.json index c701dd54704c..61c2cdc88482 100644 --- a/packages/svelte/package.json +++ b/packages/svelte/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/svelte", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for Svelte", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/svelte", @@ -39,8 +39,8 @@ "access": "public" }, "dependencies": { - "@sentry/browser": "8.45.1", - "@sentry/core": "8.45.1", + "@sentry/browser": "8.46.0", + "@sentry/core": "8.46.0", "magic-string": "^0.30.0" }, "peerDependencies": { diff --git a/packages/sveltekit/package.json b/packages/sveltekit/package.json index 3ea19028f0dd..3154883ef716 100644 --- a/packages/sveltekit/package.json +++ b/packages/sveltekit/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/sveltekit", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for SvelteKit", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/sveltekit", @@ -40,10 +40,10 @@ } }, "dependencies": { - "@sentry/core": "8.45.1", - "@sentry/node": "8.45.1", - "@sentry/opentelemetry": "8.45.1", - "@sentry/svelte": "8.45.1", + "@sentry/core": "8.46.0", + "@sentry/node": "8.46.0", + "@sentry/opentelemetry": "8.46.0", + "@sentry/svelte": "8.46.0", "@sentry/vite-plugin": "2.22.6", "magic-string": "0.30.7", "magicast": "0.2.8", diff --git a/packages/types/package.json b/packages/types/package.json index 7ffd2442d6a0..52eb76daa279 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/types", - "version": "8.45.1", + "version": "8.46.0", "description": "Types for all Sentry JavaScript SDKs", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/types", @@ -56,7 +56,7 @@ "yalc:publish": "yalc publish --push --sig" }, "dependencies": { - "@sentry/core": "8.45.1" + "@sentry/core": "8.46.0" }, "volta": { "extends": "../../package.json" diff --git a/packages/typescript/package.json b/packages/typescript/package.json index fb55b1f06894..d5bc28b162d4 100644 --- a/packages/typescript/package.json +++ b/packages/typescript/package.json @@ -1,6 +1,6 @@ { "name": "@sentry-internal/typescript", - "version": "8.45.1", + "version": "8.46.0", "description": "Typescript configuration used at Sentry", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/typescript", diff --git a/packages/utils/package.json b/packages/utils/package.json index bf29cea0aa9a..f71625a5e1bf 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/utils", - "version": "8.45.1", + "version": "8.46.0", "description": "Utilities for all Sentry JavaScript SDKs", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/utils", @@ -39,7 +39,7 @@ "access": "public" }, "dependencies": { - "@sentry/core": "8.45.1" + "@sentry/core": "8.46.0" }, "scripts": { "build": "run-p build:transpile build:types", diff --git a/packages/vercel-edge/package.json b/packages/vercel-edge/package.json index 5fc79e8a19d9..cdac92a13426 100644 --- a/packages/vercel-edge/package.json +++ b/packages/vercel-edge/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/vercel-edge", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for the Vercel Edge Runtime", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/vercel-edge", @@ -40,7 +40,7 @@ }, "dependencies": { "@opentelemetry/api": "^1.9.0", - "@sentry/core": "8.45.1" + "@sentry/core": "8.46.0" }, "devDependencies": { "@edge-runtime/types": "3.0.1", @@ -48,7 +48,7 @@ "@opentelemetry/resources": "^1.29.0", "@opentelemetry/sdk-trace-base": "^1.29.0", "@opentelemetry/semantic-conventions": "^1.28.0", - "@sentry/opentelemetry": "8.45.1" + "@sentry/opentelemetry": "8.46.0" }, "scripts": { "build": "run-p build:transpile build:types", diff --git a/packages/vue/package.json b/packages/vue/package.json index 83b4a4e9af2f..f7546f0b5019 100644 --- a/packages/vue/package.json +++ b/packages/vue/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/vue", - "version": "8.45.1", + "version": "8.46.0", "description": "Official Sentry SDK for Vue.js", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/vue", @@ -39,8 +39,8 @@ "access": "public" }, "dependencies": { - "@sentry/browser": "8.45.1", - "@sentry/core": "8.45.1" + "@sentry/browser": "8.46.0", + "@sentry/core": "8.46.0" }, "peerDependencies": { "pinia": "2.x", diff --git a/packages/wasm/package.json b/packages/wasm/package.json index 464f4fde7bb5..dc8f6b27e4c1 100644 --- a/packages/wasm/package.json +++ b/packages/wasm/package.json @@ -1,6 +1,6 @@ { "name": "@sentry/wasm", - "version": "8.45.1", + "version": "8.46.0", "description": "Support for WASM.", "repository": "git://github.com/getsentry/sentry-javascript.git", "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/wasm", @@ -39,8 +39,8 @@ "access": "public" }, "dependencies": { - "@sentry/browser": "8.45.1", - "@sentry/core": "8.45.1" + "@sentry/browser": "8.46.0", + "@sentry/core": "8.46.0" }, "scripts": { "build": "run-p build:transpile build:bundle build:types", From 3a7743c0b881872048a8049a24a10905c25cba76 Mon Sep 17 00:00:00 2001 From: Lukas Stracke Date: Tue, 17 Dec 2024 14:31:32 +0100 Subject: [PATCH 12/66] feat(core): Add `updateSpanName` helper function [v8] (#14736) Backport of #14291 to v8 --- .../pageload-update-txn-name/test.ts | 45 +-- .../pageload-updateSpanName/init.js | 10 + .../pageload-updateSpanName/subject.js | 4 + .../pageload-updateSpanName/test.ts | 43 +++ .../tracing/dsc-txn-name-update/test.ts | 4 + .../express/tracing/updateName/server.js | 58 ++++ .../suites/express/tracing/updateName/test.ts | 94 ++++++ .../public-api/startSpan/basic-usage/test.ts | 35 +- .../startSpan/updateName-method/scenario.ts | 16 + .../startSpan/updateName-method/test.ts | 24 ++ .../updateSpanName-function/scenario.ts | 16 + .../startSpan/updateSpanName-function/test.ts | 24 ++ packages/astro/src/index.server.ts | 1 + packages/aws-serverless/src/index.ts | 1 + packages/browser/src/exports.ts | 1 + packages/bun/src/index.ts | 1 + packages/cloudflare/src/index.ts | 1 + packages/core/src/index.ts | 1 + packages/core/src/semanticAttributes.ts | 9 + packages/core/src/tracing/sentrySpan.ts | 9 + packages/core/src/types-hoist/span.ts | 10 + packages/core/src/utils/spanUtils.ts | 31 +- .../core/test/lib/utils/spanUtils.test.ts | 21 +- packages/deno/src/index.ts | 1 + packages/google-cloud-serverless/src/index.ts | 1 + packages/node/src/index.ts | 1 + packages/opentelemetry/src/spanExporter.ts | 2 + .../src/utils/parseSpanDescription.ts | 96 +++++- .../test/utils/parseSpanDescription.test.ts | 307 +++++++++++++++++- packages/remix/src/index.server.ts | 1 + packages/solidstart/src/server/index.ts | 1 + packages/sveltekit/src/server/index.ts | 1 + 32 files changed, 830 insertions(+), 40 deletions(-) create mode 100644 dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-updateSpanName/init.js create mode 100644 dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-updateSpanName/subject.js create mode 100644 dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-updateSpanName/test.ts create mode 100644 dev-packages/node-integration-tests/suites/express/tracing/updateName/server.js create mode 100644 dev-packages/node-integration-tests/suites/express/tracing/updateName/test.ts create mode 100644 dev-packages/node-integration-tests/suites/public-api/startSpan/updateName-method/scenario.ts create mode 100644 dev-packages/node-integration-tests/suites/public-api/startSpan/updateName-method/test.ts create mode 100644 dev-packages/node-integration-tests/suites/public-api/startSpan/updateSpanName-function/scenario.ts create mode 100644 dev-packages/node-integration-tests/suites/public-api/startSpan/updateSpanName-function/test.ts diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-update-txn-name/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-update-txn-name/test.ts index 6226ff75dbb9..7d2d949898c2 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-update-txn-name/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-update-txn-name/test.ts @@ -1,5 +1,5 @@ import { expect } from '@playwright/test'; -import type { Event } from '@sentry/core'; +import { type Event, SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME } from '@sentry/core'; import { SEMANTIC_ATTRIBUTE_SENTRY_OP, @@ -10,27 +10,34 @@ import { import { sentryTest } from '../../../../utils/fixtures'; import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; -sentryTest('sets the source to custom when updating the transaction name', async ({ getLocalTestUrl, page }) => { - if (shouldSkipTracingTest()) { - sentryTest.skip(); - } +sentryTest( + 'sets the source to custom when updating the transaction name with `span.updateName`', + async ({ getLocalTestUrl, page }) => { + if (shouldSkipTracingTest()) { + sentryTest.skip(); + } - const url = await getLocalTestUrl({ testDir: __dirname }); + const url = await getLocalTestUrl({ testDir: __dirname }); - const eventData = await getFirstSentryEnvelopeRequest(page, url); + const eventData = await getFirstSentryEnvelopeRequest(page, url); - const traceContextData = eventData.contexts?.trace?.data; + const traceContextData = eventData.contexts?.trace?.data; - expect(traceContextData).toMatchObject({ - [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.browser', - [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, - [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', - [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'pageload', - }); + expect(traceContextData).toBeDefined(); - expect(eventData.transaction).toBe('new name'); + expect(eventData.transaction).toBe('new name'); - expect(eventData.contexts?.trace?.op).toBe('pageload'); - expect(eventData.spans?.length).toBeGreaterThan(0); - expect(eventData.transaction_info?.source).toEqual('custom'); -}); + expect(traceContextData).toMatchObject({ + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.browser', + [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'pageload', + }); + + expect(traceContextData![SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]).toBeUndefined(); + + expect(eventData.contexts?.trace?.op).toBe('pageload'); + expect(eventData.spans?.length).toBeGreaterThan(0); + expect(eventData.transaction_info?.source).toEqual('custom'); + }, +); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-updateSpanName/init.js b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-updateSpanName/init.js new file mode 100644 index 000000000000..1f0b64911a75 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-updateSpanName/init.js @@ -0,0 +1,10 @@ +import * as Sentry from '@sentry/browser'; + +window.Sentry = Sentry; +window._testBaseTimestamp = performance.timeOrigin / 1000; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + integrations: [Sentry.browserTracingIntegration()], + tracesSampleRate: 1, +}); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-updateSpanName/subject.js b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-updateSpanName/subject.js new file mode 100644 index 000000000000..7f0ad0fea340 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-updateSpanName/subject.js @@ -0,0 +1,4 @@ +const activeSpan = Sentry.getActiveSpan(); +const rootSpan = activeSpan && Sentry.getRootSpan(activeSpan); + +Sentry.updateSpanName(rootSpan, 'new name'); diff --git a/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-updateSpanName/test.ts b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-updateSpanName/test.ts new file mode 100644 index 000000000000..69094b38e4dd --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/tracing/browserTracingIntegration/pageload-updateSpanName/test.ts @@ -0,0 +1,43 @@ +import { expect } from '@playwright/test'; +import { type Event, SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME } from '@sentry/core'; + +import { + SEMANTIC_ATTRIBUTE_SENTRY_OP, + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, + SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, + SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, +} from '@sentry/browser'; +import { sentryTest } from '../../../../utils/fixtures'; +import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers'; + +sentryTest( + 'sets the source to custom when updating the transaction name with Sentry.updateSpanName', + async ({ getLocalTestUrl, page }) => { + if (shouldSkipTracingTest()) { + sentryTest.skip(); + } + + const url = await getLocalTestUrl({ testDir: __dirname }); + + const eventData = await getFirstSentryEnvelopeRequest(page, url); + + const traceContextData = eventData.contexts?.trace?.data; + + expect(traceContextData).toBeDefined(); + + expect(traceContextData).toMatchObject({ + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.pageload.browser', + [SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE]: 1, + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'pageload', + }); + + expect(traceContextData![SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]).toBeUndefined(); + + expect(eventData.transaction).toBe('new name'); + + expect(eventData.contexts?.trace?.op).toBe('pageload'); + expect(eventData.spans?.length).toBeGreaterThan(0); + expect(eventData.transaction_info?.source).toEqual('custom'); + }, +); diff --git a/dev-packages/browser-integration-tests/suites/tracing/dsc-txn-name-update/test.ts b/dev-packages/browser-integration-tests/suites/tracing/dsc-txn-name-update/test.ts index 7ce5f7195a5b..34e15d1be573 100644 --- a/dev-packages/browser-integration-tests/suites/tracing/dsc-txn-name-update/test.ts +++ b/dev-packages/browser-integration-tests/suites/tracing/dsc-txn-name-update/test.ts @@ -181,5 +181,9 @@ async function captureErrorAndGetEnvelopeTraceHeader(page: Page): Promise { + const span = Sentry.getActiveSpan(); + const rootSpan = Sentry.getRootSpan(span); + rootSpan.updateName('new-name'); + res.send({ response: 'response 1' }); +}); + +app.get('/test/:id/span-updateName-source', (_req, res) => { + const span = Sentry.getActiveSpan(); + const rootSpan = Sentry.getRootSpan(span); + rootSpan.updateName('new-name'); + rootSpan.setAttribute(Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'custom'); + res.send({ response: 'response 2' }); +}); + +app.get('/test/:id/updateSpanName', (_req, res) => { + const span = Sentry.getActiveSpan(); + const rootSpan = Sentry.getRootSpan(span); + Sentry.updateSpanName(rootSpan, 'new-name'); + res.send({ response: 'response 3' }); +}); + +app.get('/test/:id/updateSpanNameAndSource', (_req, res) => { + const span = Sentry.getActiveSpan(); + const rootSpan = Sentry.getRootSpan(span); + Sentry.updateSpanName(rootSpan, 'new-name'); + rootSpan.setAttribute(Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'component'); + res.send({ response: 'response 4' }); +}); + +Sentry.setupExpressErrorHandler(app); + +startExpressServerAndSendPortToRunner(app); diff --git a/dev-packages/node-integration-tests/suites/express/tracing/updateName/test.ts b/dev-packages/node-integration-tests/suites/express/tracing/updateName/test.ts new file mode 100644 index 000000000000..c6345713fd7e --- /dev/null +++ b/dev-packages/node-integration-tests/suites/express/tracing/updateName/test.ts @@ -0,0 +1,94 @@ +import { SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME } from '@sentry/core'; +import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/node'; +import { cleanupChildProcesses, createRunner } from '../../../../utils/runner'; + +describe('express tracing', () => { + afterAll(() => { + cleanupChildProcesses(); + }); + + describe('CJS', () => { + // This test documents the unfortunate behaviour of using `span.updateName` on the server-side. + // For http.server root spans (which is the root span on the server 99% of the time), Otel's http instrumentation + // calls `span.updateName` and overwrites whatever the name was set to before (by us or by users). + test("calling just `span.updateName` doesn't update the final name in express (missing source)", done => { + createRunner(__dirname, 'server.js') + .expect({ + transaction: { + transaction: 'GET /test/:id/span-updateName', + transaction_info: { + source: 'route', + }, + }, + }) + .start(done) + .makeRequest('get', '/test/123/span-updateName'); + }); + + // Also calling `updateName` AND setting a source doesn't change anything - Otel has no concept of source, this is sentry-internal. + // Therefore, only the source is updated but the name is still overwritten by Otel. + test("calling `span.updateName` and setting attribute source doesn't update the final name in express but it updates the source", done => { + createRunner(__dirname, 'server.js') + .expect({ + transaction: { + transaction: 'GET /test/:id/span-updateName-source', + transaction_info: { + source: 'custom', + }, + }, + }) + .start(done) + .makeRequest('get', '/test/123/span-updateName-source'); + }); + + // This test documents the correct way to update the span name (and implicitly the source) in Node: + test('calling `Sentry.updateSpanName` updates the final name and source in express', done => { + createRunner(__dirname, 'server.js') + .expect({ + transaction: txnEvent => { + expect(txnEvent).toMatchObject({ + transaction: 'new-name', + transaction_info: { + source: 'custom', + }, + contexts: { + trace: { + op: 'http.server', + data: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom' }, + }, + }, + }); + // ensure we delete the internal attribute once we're done with it + expect(txnEvent.contexts?.trace?.data?.[SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]).toBeUndefined(); + }, + }) + .start(done) + .makeRequest('get', '/test/123/updateSpanName'); + }); + }); + + // This test documents the correct way to update the span name (and implicitly the source) in Node: + test('calling `Sentry.updateSpanName` and setting source subsequently updates the final name and sets correct source', done => { + createRunner(__dirname, 'server.js') + .expect({ + transaction: txnEvent => { + expect(txnEvent).toMatchObject({ + transaction: 'new-name', + transaction_info: { + source: 'component', + }, + contexts: { + trace: { + op: 'http.server', + data: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component' }, + }, + }, + }); + // ensure we delete the internal attribute once we're done with it + expect(txnEvent.contexts?.trace?.data?.[SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]).toBeUndefined(); + }, + }) + .start(done) + .makeRequest('get', '/test/123/updateSpanNameAndSource'); + }); +}); diff --git a/dev-packages/node-integration-tests/suites/public-api/startSpan/basic-usage/test.ts b/dev-packages/node-integration-tests/suites/public-api/startSpan/basic-usage/test.ts index 86b3bf6d9d22..0370b123cab2 100644 --- a/dev-packages/node-integration-tests/suites/public-api/startSpan/basic-usage/test.ts +++ b/dev-packages/node-integration-tests/suites/public-api/startSpan/basic-usage/test.ts @@ -1,11 +1,42 @@ +import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/node'; import { cleanupChildProcesses, createRunner } from '../../../../utils/runner'; afterAll(() => { cleanupChildProcesses(); }); -test('should send a manually started root span', done => { +test('sends a manually started root span with source custom', done => { createRunner(__dirname, 'scenario.ts') - .expect({ transaction: { transaction: 'test_span' } }) + .expect({ + transaction: { + transaction: 'test_span', + transaction_info: { source: 'custom' }, + contexts: { + trace: { + span_id: expect.any(String), + trace_id: expect.any(String), + data: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom' }, + }, + }, + }, + }) + .start(done); +}); + +test("doesn't change the name for manually started spans even if attributes triggering inference are set", done => { + createRunner(__dirname, 'scenario.ts') + .expect({ + transaction: { + transaction: 'test_span', + transaction_info: { source: 'custom' }, + contexts: { + trace: { + span_id: expect.any(String), + trace_id: expect.any(String), + data: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom' }, + }, + }, + }, + }) .start(done); }); diff --git a/dev-packages/node-integration-tests/suites/public-api/startSpan/updateName-method/scenario.ts b/dev-packages/node-integration-tests/suites/public-api/startSpan/updateName-method/scenario.ts new file mode 100644 index 000000000000..ea30608c1c5c --- /dev/null +++ b/dev-packages/node-integration-tests/suites/public-api/startSpan/updateName-method/scenario.ts @@ -0,0 +1,16 @@ +import { loggingTransport } from '@sentry-internal/node-integration-tests'; +import * as Sentry from '@sentry/node'; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + release: '1.0', + tracesSampleRate: 1.0, + transport: loggingTransport, +}); + +Sentry.startSpan( + { name: 'test_span', attributes: { [Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url' } }, + (span: Sentry.Span) => { + span.updateName('new name'); + }, +); diff --git a/dev-packages/node-integration-tests/suites/public-api/startSpan/updateName-method/test.ts b/dev-packages/node-integration-tests/suites/public-api/startSpan/updateName-method/test.ts new file mode 100644 index 000000000000..676071926b91 --- /dev/null +++ b/dev-packages/node-integration-tests/suites/public-api/startSpan/updateName-method/test.ts @@ -0,0 +1,24 @@ +import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/node'; +import { cleanupChildProcesses, createRunner } from '../../../../utils/runner'; + +afterAll(() => { + cleanupChildProcesses(); +}); + +test('updates the span name when calling `span.updateName`', done => { + createRunner(__dirname, 'scenario.ts') + .expect({ + transaction: { + transaction: 'new name', + transaction_info: { source: 'url' }, + contexts: { + trace: { + span_id: expect.any(String), + trace_id: expect.any(String), + data: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url' }, + }, + }, + }, + }) + .start(done); +}); diff --git a/dev-packages/node-integration-tests/suites/public-api/startSpan/updateSpanName-function/scenario.ts b/dev-packages/node-integration-tests/suites/public-api/startSpan/updateSpanName-function/scenario.ts new file mode 100644 index 000000000000..ecf7670fa23d --- /dev/null +++ b/dev-packages/node-integration-tests/suites/public-api/startSpan/updateSpanName-function/scenario.ts @@ -0,0 +1,16 @@ +import { loggingTransport } from '@sentry-internal/node-integration-tests'; +import * as Sentry from '@sentry/node'; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + release: '1.0', + tracesSampleRate: 1.0, + transport: loggingTransport, +}); + +Sentry.startSpan( + { name: 'test_span', attributes: { [Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url' } }, + (span: Sentry.Span) => { + Sentry.updateSpanName(span, 'new name'); + }, +); diff --git a/dev-packages/node-integration-tests/suites/public-api/startSpan/updateSpanName-function/test.ts b/dev-packages/node-integration-tests/suites/public-api/startSpan/updateSpanName-function/test.ts new file mode 100644 index 000000000000..c5b325fc0ea2 --- /dev/null +++ b/dev-packages/node-integration-tests/suites/public-api/startSpan/updateSpanName-function/test.ts @@ -0,0 +1,24 @@ +import { SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/node'; +import { cleanupChildProcesses, createRunner } from '../../../../utils/runner'; + +afterAll(() => { + cleanupChildProcesses(); +}); + +test('updates the span name and source when calling `updateSpanName`', done => { + createRunner(__dirname, 'scenario.ts') + .expect({ + transaction: { + transaction: 'new name', + transaction_info: { source: 'custom' }, + contexts: { + trace: { + span_id: expect.any(String), + trace_id: expect.any(String), + data: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom' }, + }, + }, + }, + }) + .start(done); +}); diff --git a/packages/astro/src/index.server.ts b/packages/astro/src/index.server.ts index 7eca9de9a41a..ad7481816b4d 100644 --- a/packages/astro/src/index.server.ts +++ b/packages/astro/src/index.server.ts @@ -138,6 +138,7 @@ export { startSpanManual, tediousIntegration, trpcMiddleware, + updateSpanName, withActiveSpan, withIsolationScope, withMonitor, diff --git a/packages/aws-serverless/src/index.ts b/packages/aws-serverless/src/index.ts index 3f167b62a7e3..5146fe423b45 100644 --- a/packages/aws-serverless/src/index.ts +++ b/packages/aws-serverless/src/index.ts @@ -121,6 +121,7 @@ export { spanToTraceHeader, spanToBaggageHeader, trpcMiddleware, + updateSpanName, // eslint-disable-next-line deprecation/deprecation addOpenTelemetryInstrumentation, zodErrorsIntegration, diff --git a/packages/browser/src/exports.ts b/packages/browser/src/exports.ts index 492f9da23b38..295e6daa36cc 100644 --- a/packages/browser/src/exports.ts +++ b/packages/browser/src/exports.ts @@ -62,6 +62,7 @@ export { spanToJSON, spanToTraceHeader, spanToBaggageHeader, + updateSpanName, } from '@sentry/core'; export { diff --git a/packages/bun/src/index.ts b/packages/bun/src/index.ts index 1ba5f2de4786..dcae6e98aa8d 100644 --- a/packages/bun/src/index.ts +++ b/packages/bun/src/index.ts @@ -141,6 +141,7 @@ export { spanToTraceHeader, spanToBaggageHeader, trpcMiddleware, + updateSpanName, // eslint-disable-next-line deprecation/deprecation addOpenTelemetryInstrumentation, zodErrorsIntegration, diff --git a/packages/cloudflare/src/index.ts b/packages/cloudflare/src/index.ts index f3c80b8ddf32..fb8c34694282 100644 --- a/packages/cloudflare/src/index.ts +++ b/packages/cloudflare/src/index.ts @@ -89,6 +89,7 @@ export { spanToJSON, spanToTraceHeader, spanToBaggageHeader, + updateSpanName, } from '@sentry/core'; export { withSentry } from './handler'; diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 77259d2434d4..5baf88f38e1c 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -81,6 +81,7 @@ export { getActiveSpan, addChildSpanToSpan, spanTimeInputToSeconds, + updateSpanName, } from './utils/spanUtils'; export { parseSampleRate } from './utils/parseSampleRate'; export { applySdkMetadata } from './utils/sdkMetadata'; diff --git a/packages/core/src/semanticAttributes.ts b/packages/core/src/semanticAttributes.ts index 2896bd81f93f..b799f5321a0e 100644 --- a/packages/core/src/semanticAttributes.ts +++ b/packages/core/src/semanticAttributes.ts @@ -29,6 +29,15 @@ export const SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_UNIT = 'sentry.measurement_un /** The value of a measurement, which may be stored as a TimedEvent. */ export const SEMANTIC_ATTRIBUTE_SENTRY_MEASUREMENT_VALUE = 'sentry.measurement_value'; +/** + * A custom span name set by users guaranteed to be taken over any automatically + * inferred name. This attribute is removed before the span is sent. + * + * @internal only meant for internal SDK usage + * @hidden + */ +export const SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME = 'sentry.custom_span_name'; + /** * The id of the profile that this span occurred in. */ diff --git a/packages/core/src/tracing/sentrySpan.ts b/packages/core/src/tracing/sentrySpan.ts index 126702dfad2b..9965261970f2 100644 --- a/packages/core/src/tracing/sentrySpan.ts +++ b/packages/core/src/tracing/sentrySpan.ts @@ -5,6 +5,7 @@ import { getMetricSummaryJsonForSpan } from '../metrics/metric-summary'; import { SEMANTIC_ATTRIBUTE_EXCLUSIVE_TIME, SEMANTIC_ATTRIBUTE_PROFILE_ID, + SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, @@ -355,6 +356,14 @@ export class SentrySpan implements Span { const source = this._attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] as TransactionSource | undefined; + // remove internal root span attributes we don't need to send. + /* eslint-disable @typescript-eslint/no-dynamic-delete */ + delete this._attributes[SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]; + spans.forEach(span => { + span.data && delete span.data[SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]; + }); + // eslint-enabled-next-line @typescript-eslint/no-dynamic-delete + const transaction: TransactionEvent = { contexts: { trace: spanToTransactionTraceContext(this), diff --git a/packages/core/src/types-hoist/span.ts b/packages/core/src/types-hoist/span.ts index a2ee74fd7cfa..cf0c3086bf88 100644 --- a/packages/core/src/types-hoist/span.ts +++ b/packages/core/src/types-hoist/span.ts @@ -234,6 +234,16 @@ export interface Span { /** * Update the name of the span. + * + * **Important:** You most likely want to use `Sentry.updateSpanName(span, name)` instead! + * + * This method will update the current span name but cannot guarantee that the new name will be + * the final name of the span. Instrumentation might still overwrite the name with an automatically + * computed name, for example in `http.server` or `db` spans. + * + * You can ensure that your name is kept and not overwritten by calling `Sentry.updateSpanName(span, name)` + * + * @param name the new name of the span */ updateName(name: string): this; diff --git a/packages/core/src/utils/spanUtils.ts b/packages/core/src/utils/spanUtils.ts index 594a297f9395..09ba9d729449 100644 --- a/packages/core/src/utils/spanUtils.ts +++ b/packages/core/src/utils/spanUtils.ts @@ -3,7 +3,12 @@ import { getMainCarrier } from '../carrier'; import { getCurrentScope } from '../currentScopes'; import { getMetricSummaryJsonForSpan, updateMetricSummaryOnSpan } from '../metrics/metric-summary'; import type { MetricType } from '../metrics/types'; -import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../semanticAttributes'; +import { + SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME, + SEMANTIC_ATTRIBUTE_SENTRY_OP, + SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, + SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, +} from '../semanticAttributes'; import type { SentrySpan } from '../tracing/sentrySpan'; import { SPAN_STATUS_OK, SPAN_STATUS_UNSET } from '../tracing/spanstatus'; import type { @@ -310,3 +315,27 @@ export function showSpanDropWarning(): void { hasShownSpanDropWarning = true; } } + +/** + * Updates the name of the given span and ensures that the span name is not + * overwritten by the Sentry SDK. + * + * Use this function instead of `span.updateName()` if you want to make sure that + * your name is kept. For some spans, for example root `http.server` spans the + * Sentry SDK would otherwise overwrite the span name with a high-quality name + * it infers when the span ends. + * + * Use this function in server code or when your span is started on the server + * and on the client (browser). If you only update a span name on the client, + * you can also use `span.updateName()` the SDK does not overwrite the name. + * + * @param span - The span to update the name of. + * @param name - The name to set on the span. + */ +export function updateSpanName(span: Span, name: string): void { + span.updateName(name); + span.setAttributes({ + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', + [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: name, + }); +} diff --git a/packages/core/test/lib/utils/spanUtils.test.ts b/packages/core/test/lib/utils/spanUtils.test.ts index f7187695a025..aa6d4bf4cb2f 100644 --- a/packages/core/test/lib/utils/spanUtils.test.ts +++ b/packages/core/test/lib/utils/spanUtils.test.ts @@ -1,6 +1,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, + SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, SPAN_STATUS_ERROR, SPAN_STATUS_OK, SPAN_STATUS_UNSET, @@ -14,8 +15,14 @@ import { } from '../../../src'; import type { Span, SpanAttributes, SpanStatus, SpanTimeInput } from '../../../src/types-hoist'; import type { OpenTelemetrySdkTraceBaseSpan } from '../../../src/utils/spanUtils'; -import { spanToTraceContext } from '../../../src/utils/spanUtils'; -import { getRootSpan, spanIsSampled, spanTimeInputToSeconds, spanToJSON } from '../../../src/utils/spanUtils'; +import { + getRootSpan, + spanIsSampled, + spanTimeInputToSeconds, + spanToJSON, + spanToTraceContext, + updateSpanName, +} from '../../../src/utils/spanUtils'; import { TestClient, getDefaultTestClientOptions } from '../../mocks/client'; function createMockedOtelSpan({ @@ -332,3 +339,13 @@ describe('getRootSpan', () => { }); }); }); + +describe('updateSpanName', () => { + it('updates the span name and source', () => { + const span = new SentrySpan({ name: 'old-name', attributes: { [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url' } }); + updateSpanName(span, 'new-name'); + const spanJSON = spanToJSON(span); + expect(spanJSON.description).toBe('new-name'); + expect(spanJSON.data?.[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]).toBe('custom'); + }); +}); diff --git a/packages/deno/src/index.ts b/packages/deno/src/index.ts index 892f6ce681c0..cea4effad4bd 100644 --- a/packages/deno/src/index.ts +++ b/packages/deno/src/index.ts @@ -89,6 +89,7 @@ export { spanToJSON, spanToTraceHeader, spanToBaggageHeader, + updateSpanName, } from '@sentry/core'; export { DenoClient } from './client'; diff --git a/packages/google-cloud-serverless/src/index.ts b/packages/google-cloud-serverless/src/index.ts index 6f89769c2a37..95d30ec8b072 100644 --- a/packages/google-cloud-serverless/src/index.ts +++ b/packages/google-cloud-serverless/src/index.ts @@ -118,6 +118,7 @@ export { spanToTraceHeader, spanToBaggageHeader, trpcMiddleware, + updateSpanName, // eslint-disable-next-line deprecation/deprecation addOpenTelemetryInstrumentation, zodErrorsIntegration, diff --git a/packages/node/src/index.ts b/packages/node/src/index.ts index fa16ac4e6b3d..215d53bdbde3 100644 --- a/packages/node/src/index.ts +++ b/packages/node/src/index.ts @@ -142,6 +142,7 @@ export { spanToTraceHeader, spanToBaggageHeader, trpcMiddleware, + updateSpanName, zodErrorsIntegration, profiler, } from '@sentry/core'; diff --git a/packages/opentelemetry/src/spanExporter.ts b/packages/opentelemetry/src/spanExporter.ts index a8d5affa4646..bff6518eb27d 100644 --- a/packages/opentelemetry/src/spanExporter.ts +++ b/packages/opentelemetry/src/spanExporter.ts @@ -12,6 +12,7 @@ import type { TransactionSource, } from '@sentry/core'; import { + SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, SEMANTIC_ATTRIBUTE_SENTRY_SAMPLE_RATE, @@ -392,6 +393,7 @@ function removeSentryAttributes(data: Record): Record = {}; @@ -174,12 +198,21 @@ export function descriptionForHttpMethod( const origin = attributes[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN] || 'manual'; const isManualSpan = !`${origin}`.startsWith('auto'); - const useInferredDescription = isClientOrServerKind || !isManualSpan; + // If users (or in very rare occasions we) set the source to custom, we don't overwrite the name + const alreadyHasCustomSource = attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] === 'custom'; + const customSpanName = attributes[SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]; + + const useInferredDescription = + !alreadyHasCustomSource && customSpanName == null && (isClientOrServerKind || !isManualSpan); + + const { description, source } = useInferredDescription + ? { description: inferredDescription, source: inferredSource } + : getUserUpdatedNameAndSource(name, attributes); return { op: opParts.join('.'), - description: useInferredDescription ? description : name, - source: useInferredDescription ? source : 'custom', + description, + source, data, }; } @@ -244,3 +277,36 @@ export function getSanitizedUrl( return { urlPath: undefined, url, query, fragment, hasRoute: false }; } + +/** + * Because Otel instrumentation sometimes mutates span names via `span.updateName`, the only way + * to ensure that a user-set span name is preserved is to store it as a tmp attribute on the span. + * We delete this attribute once we're done with it when preparing the event envelope. + * + * This temp attribute always takes precedence over the original name. + * + * We also need to take care of setting the correct source. Users can always update the source + * after updating the name, so we need to respect that. + * + * @internal exported only for testing + */ +export function getUserUpdatedNameAndSource( + originalName: string, + attributes: Attributes, + fallbackSource: TransactionSource = 'custom', +): { + description: string; + source: TransactionSource; +} { + const source = (attributes[SEMANTIC_ATTRIBUTE_SENTRY_SOURCE] as TransactionSource) || fallbackSource; + const description = attributes[SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]; + + if (description && typeof description === 'string') { + return { + description, + source, + }; + } + + return { description: originalName, source }; +} diff --git a/packages/opentelemetry/test/utils/parseSpanDescription.test.ts b/packages/opentelemetry/test/utils/parseSpanDescription.test.ts index c44645c62888..d43dfcd9f587 100644 --- a/packages/opentelemetry/test/utils/parseSpanDescription.test.ts +++ b/packages/opentelemetry/test/utils/parseSpanDescription.test.ts @@ -15,7 +15,13 @@ import { SEMATTRS_RPC_SERVICE, } from '@opentelemetry/semantic-conventions'; -import { descriptionForHttpMethod, getSanitizedUrl, parseSpanDescription } from '../../src/utils/parseSpanDescription'; +import { SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME, SEMANTIC_ATTRIBUTE_SENTRY_SOURCE } from '@sentry/core'; +import { + descriptionForHttpMethod, + getSanitizedUrl, + getUserUpdatedNameAndSource, + parseSpanDescription, +} from '../../src/utils/parseSpanDescription'; describe('parseSpanDescription', () => { it.each([ @@ -81,6 +87,53 @@ describe('parseSpanDescription', () => { source: 'task', }, ], + [ + 'works with db system and custom source', + { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', + [SEMATTRS_DB_SYSTEM]: 'mysql', + [SEMATTRS_DB_STATEMENT]: 'SELECT * from users', + }, + 'test name', + SpanKind.CLIENT, + { + description: 'test name', + op: 'db', + source: 'custom', + }, + ], + [ + 'works with db system and custom source and custom name', + { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', + [SEMATTRS_DB_SYSTEM]: 'mysql', + [SEMATTRS_DB_STATEMENT]: 'SELECT * from users', + [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 'custom name', + }, + 'test name', + SpanKind.CLIENT, + { + description: 'custom name', + op: 'db', + source: 'custom', + }, + ], + [ + 'works with db system and component source and custom name', + { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMATTRS_DB_SYSTEM]: 'mysql', + [SEMATTRS_DB_STATEMENT]: 'SELECT * from users', + [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 'custom name', + }, + 'test name', + SpanKind.CLIENT, + { + description: 'custom name', + op: 'db', + source: 'component', + }, + ], [ 'works with db system without statement', { @@ -107,6 +160,50 @@ describe('parseSpanDescription', () => { source: 'route', }, ], + [ + 'works with rpc service and custom source', + { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', + [SEMATTRS_RPC_SERVICE]: 'rpc-test-service', + }, + 'test name', + undefined, + { + description: 'test name', + op: 'rpc', + source: 'custom', + }, + ], + [ + 'works with rpc service and custom source and custom name', + { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', + [SEMATTRS_RPC_SERVICE]: 'rpc-test-service', + [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 'custom name', + }, + 'test name', + undefined, + { + description: 'custom name', + op: 'rpc', + source: 'custom', + }, + ], + [ + 'works with rpc service and component source and custom name', + { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMATTRS_RPC_SERVICE]: 'rpc-test-service', + [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 'custom name', + }, + 'test name', + undefined, + { + description: 'custom name', + op: 'rpc', + source: 'component', + }, + ], [ 'works with messaging system', { @@ -120,6 +217,50 @@ describe('parseSpanDescription', () => { source: 'route', }, ], + [ + 'works with messaging system and custom source', + { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', + [SEMATTRS_MESSAGING_SYSTEM]: 'test-messaging-system', + }, + 'test name', + undefined, + { + description: 'test name', + op: 'message', + source: 'custom', + }, + ], + [ + 'works with messaging system and custom source and custom name', + { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', + [SEMATTRS_MESSAGING_SYSTEM]: 'test-messaging-system', + [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 'custom name', + }, + 'test name', + undefined, + { + description: 'custom name', + op: 'message', + source: 'custom', + }, + ], + [ + 'works with messaging system and component source and custom name', + { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMATTRS_MESSAGING_SYSTEM]: 'test-messaging-system', + [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 'custom name', + }, + 'test name', + undefined, + { + description: 'custom name', + op: 'message', + source: 'component', + }, + ], [ 'works with faas trigger', { @@ -133,6 +274,50 @@ describe('parseSpanDescription', () => { source: 'route', }, ], + [ + 'works with faas trigger and custom source', + { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', + [SEMATTRS_FAAS_TRIGGER]: 'test-faas-trigger', + }, + 'test name', + undefined, + { + description: 'test name', + op: 'test-faas-trigger', + source: 'custom', + }, + ], + [ + 'works with faas trigger and custom source and custom name', + { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', + [SEMATTRS_FAAS_TRIGGER]: 'test-faas-trigger', + [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 'custom name', + }, + 'test name', + undefined, + { + description: 'custom name', + op: 'test-faas-trigger', + source: 'custom', + }, + ], + [ + 'works with faas trigger and component source and custom name', + { + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMATTRS_FAAS_TRIGGER]: 'test-faas-trigger', + [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 'custom name', + }, + 'test name', + undefined, + { + description: 'custom name', + op: 'test-faas-trigger', + source: 'component', + }, + ], ])('%s', (_, attributes, name, kind, expected) => { const actual = parseSpanDescription({ attributes, kind, name } as unknown as Span); expect(actual).toEqual(expected); @@ -172,6 +357,26 @@ describe('descriptionForHttpMethod', () => { source: 'url', }, ], + [ + 'works with prefetch request', + 'GET', + { + [SEMATTRS_HTTP_METHOD]: 'GET', + [SEMATTRS_HTTP_URL]: 'https://www.example.com/my-path', + [SEMATTRS_HTTP_TARGET]: '/my-path', + 'sentry.http.prefetch': true, + }, + 'test name', + SpanKind.CLIENT, + { + op: 'http.client.prefetch', + description: 'GET https://www.example.com/my-path', + data: { + url: 'https://www.example.com/my-path', + }, + source: 'url', + }, + ], [ 'works with basic server POST', 'POST', @@ -230,6 +435,71 @@ describe('descriptionForHttpMethod', () => { source: 'custom', }, ], + [ + "doesn't overwrite span name with source custom", + 'GET', + { + [SEMATTRS_HTTP_METHOD]: 'GET', + [SEMATTRS_HTTP_URL]: 'https://www.example.com/my-path/123', + [SEMATTRS_HTTP_TARGET]: '/my-path/123', + [ATTR_HTTP_ROUTE]: '/my-path/:id', + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', + }, + 'test name', + SpanKind.CLIENT, + { + op: 'http.client', + description: 'test name', + data: { + url: 'https://www.example.com/my-path/123', + }, + source: 'custom', + }, + ], + [ + 'takes user-passed span name (with source custom)', + 'GET', + { + [SEMATTRS_HTTP_METHOD]: 'GET', + [SEMATTRS_HTTP_URL]: 'https://www.example.com/my-path/123', + [SEMATTRS_HTTP_TARGET]: '/my-path/123', + [ATTR_HTTP_ROUTE]: '/my-path/:id', + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'custom', + [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 'custom name', + }, + 'test name', + SpanKind.CLIENT, + { + op: 'http.client', + description: 'custom name', + data: { + url: 'https://www.example.com/my-path/123', + }, + source: 'custom', + }, + ], + [ + 'takes user-passed span name (with source component)', + 'GET', + { + [SEMATTRS_HTTP_METHOD]: 'GET', + [SEMATTRS_HTTP_URL]: 'https://www.example.com/my-path/123', + [SEMATTRS_HTTP_TARGET]: '/my-path/123', + [ATTR_HTTP_ROUTE]: '/my-path/:id', + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'component', + [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 'custom name', + }, + 'test name', + SpanKind.CLIENT, + { + op: 'http.client', + description: 'custom name', + data: { + url: 'https://www.example.com/my-path/123', + }, + source: 'component', + }, + ], ])('%s', (_, httpMethod, attributes, name, kind, expected) => { const actual = descriptionForHttpMethod({ attributes, kind, name }, httpMethod); expect(actual).toEqual(expected); @@ -383,3 +653,38 @@ describe('getSanitizedUrl', () => { expect(actual).toEqual(expected); }); }); + +describe('getUserUpdatedNameAndSource', () => { + it('returns param name if `SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME` attribute is not set', () => { + expect(getUserUpdatedNameAndSource('base name', {})).toEqual({ description: 'base name', source: 'custom' }); + }); + + it('returns param name with custom fallback source if `SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME` attribute is not set', () => { + expect(getUserUpdatedNameAndSource('base name', {}, 'route')).toEqual({ + description: 'base name', + source: 'route', + }); + }); + + it('returns param name if `SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME` attribute is not a string', () => { + expect(getUserUpdatedNameAndSource('base name', { [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 123 })).toEqual({ + description: 'base name', + source: 'custom', + }); + }); + + it.each(['custom', 'task', 'url', 'route'])( + 'returns `SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME` attribute if is a string and source is %s', + source => { + expect( + getUserUpdatedNameAndSource('base name', { + [SEMANTIC_ATTRIBUTE_SENTRY_CUSTOM_SPAN_NAME]: 'custom name', + [SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: source, + }), + ).toEqual({ + description: 'custom name', + source, + }); + }, + ); +}); diff --git a/packages/remix/src/index.server.ts b/packages/remix/src/index.server.ts index f6a5f5060dd9..4bb6539dbd33 100644 --- a/packages/remix/src/index.server.ts +++ b/packages/remix/src/index.server.ts @@ -134,6 +134,7 @@ export { startSpanManual, tediousIntegration, trpcMiddleware, + updateSpanName, withActiveSpan, withIsolationScope, withMonitor, diff --git a/packages/solidstart/src/server/index.ts b/packages/solidstart/src/server/index.ts index 450420a2b586..4c1f192b0c36 100644 --- a/packages/solidstart/src/server/index.ts +++ b/packages/solidstart/src/server/index.ts @@ -126,6 +126,7 @@ export { startSpanManual, tediousIntegration, trpcMiddleware, + updateSpanName, withActiveSpan, withIsolationScope, withMonitor, diff --git a/packages/sveltekit/src/server/index.ts b/packages/sveltekit/src/server/index.ts index bb88e121244f..4996dcc0e7ca 100644 --- a/packages/sveltekit/src/server/index.ts +++ b/packages/sveltekit/src/server/index.ts @@ -128,6 +128,7 @@ export { startSpanManual, tediousIntegration, trpcMiddleware, + updateSpanName, withActiveSpan, withIsolationScope, withMonitor, From 9c53d4869ebd95ae5ad4847f9454656377790833 Mon Sep 17 00:00:00 2001 From: Francesco Gringl-Novy Date: Tue, 17 Dec 2024 15:47:18 +0100 Subject: [PATCH 13/66] feat(v8/node/deps): Bump @prisma/instrumentation from 5.19.1 to 5.22.0 (#14755) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backport of https://github.com/getsentry/sentry-javascript/pull/14753: Bump [@prisma/instrumentation](https://github.com/prisma/prisma/tree/HEAD/packages/instrumentation) from 5.19.1 to 5.22.0. See https://github.com/prisma/prisma/releases/tag/5.22.0 for release notes. This is to take advantage of the following change in 5.22.0: > In our ongoing effort to stabilize the tracing Preview feature, we’ve made our spans compliant with OpenTelemetry Semantic Conventions for Database Client Calls. **This should lead to better compatibility with tools such as DataDog and Sentry** [emphasis added by me]. There's also this change in [5.21.0](https://github.com/prisma/prisma/releases/tag/5.21.0): > The `tracing` Preview feature now has full support for MongoDB with previously missing functionality now implemented. This is a part of the ongoing effort to stabilize this Preview feature and release it in General Availability. The @dependabot PR for `@prisma/instrumentation` updates this to 6.0.0, which unfortunately drops Node.JS v18 support, so it isn't suitable for Sentry v8: https://github.com/getsentry/sentry-javascript/pull/14624 --- CHANGELOG.md | 4 ++++ packages/node/package.json | 2 +- yarn.lock | 31 +++++++++++++++++++++++++------ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb7a3f2421e9..d81eed594c2e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ - "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott +Work in this release was contributed by @aloisklink. Thank you for your contribution! + ## 8.46.0 - feat: Allow capture of more than 1 ANR event [v8] ([#14713](https://github.com/getsentry/sentry-javascript/pull/14713)) @@ -23,6 +25,8 @@ Work in this release was contributed by @conor-ob. Thank you for your contributi - fix(feedback): Return when the `sendFeedback` promise resolves ([#14683](https://github.com/getsentry/sentry-javascript/pull/14683)) +Work in this release was contributed by @antonis. Thank you for your contribution! + ## 8.45.0 - feat(core): Add `handled` option to `captureConsoleIntegration` ([#14664](https://github.com/getsentry/sentry-javascript/pull/14664)) diff --git a/packages/node/package.json b/packages/node/package.json index 5f98c240269b..53a0e62dc225 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -96,7 +96,7 @@ "@opentelemetry/resources": "^1.29.0", "@opentelemetry/sdk-trace-base": "^1.29.0", "@opentelemetry/semantic-conventions": "^1.28.0", - "@prisma/instrumentation": "5.19.1", + "@prisma/instrumentation": "5.22.0", "@sentry/core": "8.46.0", "@sentry/opentelemetry": "8.46.0", "import-in-the-middle": "^1.11.2" diff --git a/yarn.lock b/yarn.lock index e2f483ec6322..9a549f168710 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7554,6 +7554,13 @@ dependencies: "@opentelemetry/api" "^1.0.0" +"@opentelemetry/api-logs@0.53.0": + version "0.53.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/api-logs/-/api-logs-0.53.0.tgz#c478cbd8120ec2547b64edfa03a552cfe42170be" + integrity sha512-8HArjKx+RaAI8uEIgcORbZIPklyh1YLjPSBus8hjRmvLi6DeFzgOcdZ7KwPabKj8mXF8dX0hyfAyGfycz0DbFw== + dependencies: + "@opentelemetry/api" "^1.0.0" + "@opentelemetry/api-logs@0.56.0": version "0.56.0" resolved "https://registry.yarnpkg.com/@opentelemetry/api-logs/-/api-logs-0.56.0.tgz#68f8c51ca905c260b610c8a3c67d3f9fa3d59a45" @@ -7838,7 +7845,19 @@ semver "^7.5.2" shimmer "^1.2.1" -"@opentelemetry/instrumentation@^0.49 || ^0.50 || ^0.51 || ^0.52.0", "@opentelemetry/instrumentation@^0.52.1": +"@opentelemetry/instrumentation@^0.49 || ^0.50 || ^0.51 || ^0.52.0 || ^0.53.0": + version "0.53.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.53.0.tgz#e6369e4015eb5112468a4d45d38dcada7dad892d" + integrity sha512-DMwg0hy4wzf7K73JJtl95m/e0boSoWhH07rfvHvYzQtBD3Bmv0Wc1x733vyZBqmFm8OjJD0/pfiUg1W3JjFX0A== + dependencies: + "@opentelemetry/api-logs" "0.53.0" + "@types/shimmer" "^1.2.0" + import-in-the-middle "^1.8.1" + require-in-the-middle "^7.1.1" + semver "^7.5.2" + shimmer "^1.2.1" + +"@opentelemetry/instrumentation@^0.52.1": version "0.52.1" resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation/-/instrumentation-0.52.1.tgz#2e7e46a38bd7afbf03cf688c862b0b43418b7f48" integrity sha512-uXJbYU/5/MBHjMp1FqrILLRuiJCs3Ofk0MeRDk8g1S1gD47U8X3JnSwcMO1rtRo1x1a7zKaQHaoYu49p/4eSKw== @@ -8046,13 +8065,13 @@ resolved "https://registry.yarnpkg.com/@prisma/client/-/client-5.9.1.tgz#d92bd2f7f006e0316cb4fda9d73f235965cf2c64" integrity sha512-caSOnG4kxcSkhqC/2ShV7rEoWwd3XrftokxJqOCMVvia4NYV/TPtJlS9C2os3Igxw/Qyxumj9GBQzcStzECvtQ== -"@prisma/instrumentation@5.19.1": - version "5.19.1" - resolved "https://registry.yarnpkg.com/@prisma/instrumentation/-/instrumentation-5.19.1.tgz#146319cf85f22b7a43296f0f40cfeac55516e66e" - integrity sha512-VLnzMQq7CWroL5AeaW0Py2huiNKeoMfCH3SUxstdzPrlWQi6UQ9UrfcbUkNHlVFqOMacqy8X/8YtE0kuKDpD9w== +"@prisma/instrumentation@5.22.0": + version "5.22.0" + resolved "https://registry.yarnpkg.com/@prisma/instrumentation/-/instrumentation-5.22.0.tgz#c39941046e9886e17bdb47dbac45946c24d579aa" + integrity sha512-LxccF392NN37ISGxIurUljZSh1YWnphO34V5a0+T7FVQG2u9bhAXRTJpgmQ3483woVhkraQZFF7cbRrpbw/F4Q== dependencies: "@opentelemetry/api" "^1.8" - "@opentelemetry/instrumentation" "^0.49 || ^0.50 || ^0.51 || ^0.52.0" + "@opentelemetry/instrumentation" "^0.49 || ^0.50 || ^0.51 || ^0.52.0 || ^0.53.0" "@opentelemetry/sdk-trace-base" "^1.22" "@protobuf-ts/plugin-framework@^2.0.7", "@protobuf-ts/plugin-framework@^2.9.4": From 8e0db866e3be8b3758b4597596b29468943d9854 Mon Sep 17 00:00:00 2001 From: Andrei <168741329+andreiborza@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:50:26 +0100 Subject: [PATCH 14/66] chore(docs): Add docs for how to publish a release for previous majors (#14740) Backporting the release docs for older branches. --- docs/assets/run-release-workflow.png | Bin 0 -> 82385 bytes docs/publishing-a-release.md | 15 +++++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 docs/assets/run-release-workflow.png diff --git a/docs/assets/run-release-workflow.png b/docs/assets/run-release-workflow.png new file mode 100644 index 0000000000000000000000000000000000000000..50af8d111fe8ebfaaa3596363f127e42e1f3cea7 GIT binary patch literal 82385 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