diff --git a/.craft.yml b/.craft.yml index 1eb3f49530e7..d387e917307d 100644 --- a/.craft.yml +++ b/.craft.yml @@ -183,6 +183,8 @@ targets: format: base64 'npm:@sentry/bun': onlyIfPresent: /^sentry-bun-\d.*\.tgz$/ + 'npm:@sentry/cloudflare': + onlyIfPresent: /^sentry-cloudflare-\d.*\.tgz$/ 'npm:@sentry/deno': onlyIfPresent: /^sentry-deno-\d.*\.tgz$/ 'npm:@sentry/ember': diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9afeaec5947a..c160b8752a26 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -126,6 +126,7 @@ jobs: - *shared - *node - 'dev-packages/node-integration-tests/**' + - 'packages/nestjs/**' nextjs: - *shared - *browser @@ -408,10 +409,11 @@ jobs: DEPENDENCY_CACHE_KEY: ${{ needs.job_build.outputs.dependency_cache_key }} - name: Extract Profiling Node Prebuilt Binaries - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: - name: profiling-node-binaries-${{ github.sha }} + pattern: profiling-node-binaries-${{ github.sha }}-* path: ${{ github.workspace }}/packages/profiling-node/lib/ + merge-multiple: true - name: Pack tarballs run: yarn build:tarball @@ -901,16 +903,15 @@ jobs: run: yarn lerna run build:lib --scope @sentry/profiling-node - name: Extract Profiling Node Prebuilt Binaries - # @TODO: v4 breaks convenient merging of same name artifacts - # https://github.com/actions/upload-artifact/issues/478 if: | (needs.job_get_metadata.outputs.changed_profiling_node_bindings == 'true') || (needs.job_get_metadata.outputs.is_release == 'true') || (github.event_name != 'pull_request') - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: - name: profiling-node-binaries-${{ github.sha }} + pattern: profiling-node-binaries-${{ github.sha }}-* path: ${{ github.workspace }}/packages/profiling-node/lib/ + merge-multiple: true - name: Build Profiling tarball run: yarn build:tarball @@ -1230,11 +1231,11 @@ jobs: - name: Build Profiling Node run: yarn lerna run build:lib --scope @sentry/profiling-node - name: Extract Profiling Node Prebuilt Binaries - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: - name: profiling-node-binaries-${{ github.sha }} + pattern: profiling-node-binaries-${{ github.sha }}-* path: ${{ github.workspace }}/packages/profiling-node/lib/ - + merge-multiple: true - name: Restore tarball cache uses: actions/cache/restore@v4 with: @@ -1358,104 +1359,132 @@ jobs: # x64 glibc - os: ubuntu-20.04 node: 16 + binary: linux-x64-glibc-93 - os: ubuntu-20.04 node: 18 + binary: linux-x64-glibc-108 - os: ubuntu-20.04 node: 20 + binary: linux-x64-glibc-115 - os: ubuntu-20.04 node: 22 + binary: linux-x64-glibc-127 # x64 musl - os: ubuntu-20.04 container: node:16-alpine3.16 + binary: linux-x64-musl-93 node: 16 - os: ubuntu-20.04 container: node:18-alpine3.17 node: 18 + binary: linux-x64-musl-108 - os: ubuntu-20.04 container: node:20-alpine3.17 node: 20 + binary: linux-x64-musl-115 - os: ubuntu-20.04 container: node:22-alpine3.18 node: 22 + binary: linux-x64-musl-127 # arm64 glibc - os: ubuntu-20.04 arch: arm64 node: 16 + binary: linux-arm64-glibc-93 - os: ubuntu-20.04 arch: arm64 node: 18 + binary: linux-arm64-glibc-108 - os: ubuntu-20.04 arch: arm64 node: 20 + binary: linux-arm64-glibc-115 - os: ubuntu-20.04 arch: arm64 node: 22 + binary: linux-arm64-glibc-127 # arm64 musl - os: ubuntu-20.04 container: node:16-alpine3.16 arch: arm64 node: 16 + binary: linux-arm64-musl-93 - os: ubuntu-20.04 arch: arm64 container: node:18-alpine3.17 node: 18 + binary: linux-arm64-musl-108 - os: ubuntu-20.04 arch: arm64 container: node:20-alpine3.17 node: 20 + binary: linux-arm64-musl-115 - os: ubuntu-20.04 arch: arm64 container: node:22-alpine3.18 node: 22 + binary: linux-arm64-musl-127 # macos x64 - os: macos-13 node: 16 arch: x64 + binary: darwin-x64-93 - os: macos-13 node: 18 arch: x64 + binary: darwin-x64-108 - os: macos-13 node: 20 arch: x64 + binary: darwin-x64-115 - os: macos-13 node: 22 arch: x64 + binary: darwin-x64-127 # macos arm64 - os: macos-13 arch: arm64 node: 16 target_platform: darwin + binary: darwin-arm64-93 - os: macos-13 arch: arm64 node: 18 target_platform: darwin + binary: darwin-arm64-108 - os: macos-13 arch: arm64 node: 20 target_platform: darwin + binary: darwin-arm64-115 - os: macos-13 arch: arm64 node: 22 target_platform: darwin + binary: darwin-arm64-127 # windows x64 - os: windows-2022 node: 16 arch: x64 + binary: win32-x64-93 - os: windows-2022 node: 18 arch: x64 + binary: win32-x64-108 - os: windows-2022 node: 20 arch: x64 + binary: win32-x64-115 - os: windows-2022 node: 22 arch: x64 + binary: win32-x64-127 steps: - name: Setup (alpine) @@ -1587,10 +1616,8 @@ jobs: yarn lerna run test --scope @sentry/profiling-node - name: Archive Binary - # @TODO: v4 breaks convenient merging of same name artifacts - # https://github.com/actions/upload-artifact/issues/478 - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: - name: profiling-node-binaries-${{ github.sha }} - path: | - ${{ github.workspace }}/packages/profiling-node/lib/*.node + name: profiling-node-binaries-${{ github.sha }}-${{ matrix.binary }} + path: ${{ github.workspace }}/packages/profiling-node/lib/sentry_cpu_profiler-${{matrix.binary}}.node + if-no-files-found: error diff --git a/CHANGELOG.md b/CHANGELOG.md index 80a592cd4575..3eeb60765430 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,10 @@ # Changelog -> [!IMPORTANT] Important -> + +> [!IMPORTANT] > If you are upgrading to the `8.x` versions of the SDK from `7.x` or below, make sure you follow our > [migration guide](https://docs.sentry.io/platforms/javascript/migration/) first. + ## Unreleased @@ -11,13 +12,39 @@ ## 8.23.0 -- feat(cloudflare): Add Cloudflare D1 instrumentation (#13142) +### Important Changes + +- **feat(cloudflare): Add Cloudflare D1 instrumentation (#13142)** + +This release includes support for Cloudflare D1, Cloudflare's serverless SQL database. To instrument your Cloudflare D1 +database, use the `instrumentD1WithSentry` method as follows: + +```ts +// env.DB is the D1 DB binding configured in your `wrangler.toml` +const db = instrumentD1WithSentry(env.DB); +// Now you can use the database as usual +await db.prepare('SELECT * FROM table WHERE id = ?').bind(1).run(); +``` + +### Other Changes + +- feat(cloudflare): Allow users to pass handler to sentryPagesPlugin (#13192) +- feat(cloudflare): Instrument scheduled handler (#13114) +- feat(core): Add `getTraceData` function (#13134) - feat(nestjs): Automatic instrumentation of nestjs interceptors before route execution (#13153) - feat(nestjs): Automatic instrumentation of nestjs pipes (#13137) - feat(nuxt): Filter out Nuxt build assets (#13148) -- feat(profiling): attach sdk info to chunks (#13145) +- feat(profiling): Attach sdk info to chunks (#13145) +- feat(solidstart): Add sentry `onBeforeResponse` middleware to enable distributed tracing (#13221) +- feat(solidstart): Filter out low quality transactions for build assets (#13222) - fix(browser): Avoid showing browser extension error message in non-`window` global scopes (#13156) +- fix(feedback): Call dialog.close() in dialog close callbacks in `\_loadAndRenderDialog` (#13203) - fix(nestjs): Inline Observable type to resolve missing 'rxjs' dependency (#13166) +- fix(nuxt): Detect pageload by adding flag in Vue router (#13171) +- fix(utils): Handle when requests get aborted in fetch instrumentation (#13202) +- ref(browser): Improve browserMetrics collection (#13062) + +Work in this release was contributed by @horochx. Thank you for your contribution! ## 8.22.0 diff --git a/README.md b/README.md index f164af08538a..3309f0521986 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,10 @@ faster, so we can get back to enjoying technology. If you want to join us # Official Sentry SDKs for JavaScript + + + + This is the next line of Sentry JavaScript SDKs, comprised in the `@sentry/` namespace. It will provide a more convenient interface and improved consistency between various JavaScript environments. diff --git a/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withAbortController/init.js b/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withAbortController/init.js new file mode 100644 index 000000000000..7c200c542c56 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withAbortController/init.js @@ -0,0 +1,8 @@ +import * as Sentry from '@sentry/browser'; + +window.Sentry = Sentry; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + tracesSampleRate: 1, +}); diff --git a/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withAbortController/subject.js b/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withAbortController/subject.js new file mode 100644 index 000000000000..78028b473ad7 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withAbortController/subject.js @@ -0,0 +1,36 @@ +let controller; + +const startFetch = e => { + controller = new AbortController(); + const { signal } = controller; + + Sentry.startSpan( + { + name: 'with-abort-controller', + forceTransaction: true, + }, + async () => { + await fetch('http://localhost:7654/foo', { signal }) + .then(response => response.json()) + .then(data => { + console.log('Fetch succeeded:', data); + }) + .catch(err => { + if (err.name === 'AbortError') { + console.log('Fetch aborted'); + } else { + console.error('Fetch error:', err); + } + }); + }, + ); +}; + +const abortFetch = e => { + if (controller) { + controller.abort(); + } +}; + +document.querySelector('[data-test-id=start-button]').addEventListener('click', startFetch); +document.querySelector('[data-test-id=abort-button]').addEventListener('click', abortFetch); diff --git a/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withAbortController/template.html b/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withAbortController/template.html new file mode 100644 index 000000000000..18cd917fe30f --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withAbortController/template.html @@ -0,0 +1,10 @@ + + +
+ + + + + + + diff --git a/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withAbortController/test.ts b/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withAbortController/test.ts new file mode 100644 index 000000000000..6cc3a0cd32a9 --- /dev/null +++ b/dev-packages/browser-integration-tests/suites/integrations/httpclient/fetch/withAbortController/test.ts @@ -0,0 +1,41 @@ +import { expect } from '@playwright/test'; +import type { Event as SentryEvent } from '@sentry/types'; +import { sentryTest } from '../../../../../utils/fixtures'; +import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../../utils/helpers'; + +sentryTest('should handle aborted fetch calls', async ({ getLocalTestPath, page }) => { + if (shouldSkipTracingTest()) { + sentryTest.skip(); + } + + const url = await getLocalTestPath({ testDir: __dirname }); + + await page.route('**/foo', async () => { + // never fulfil this route because we abort the request as part of the test + }); + + const transactionEventPromise = getFirstSentryEnvelopeRequest = P extends ExportedHandler