Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,59 @@

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

## 10.15.0

### Important Changes

- **feat(cloudflare): Add honoIntegration with error-filtering function ([#17743](https://github.com/getsentry/sentry-javascript/pull/17743))**

This release adds a `honoIntegration` to `@sentry/cloudflare`, which exposes a `shouldHandleError` function that lets you define which errors in `onError` should be captured.
By default, Sentry captures exceptions with `error.status >= 500 || error.status <= 299`.

The integration is added by default, and it's possible to modify this behavior like this:

```js
integrations: [
honoIntegration({
shouldHandleError: (err) => true; // always capture exceptions in onError
})
]
```

- **feat(node): Add instrumentation for hono handler ([#17428](https://github.com/getsentry/sentry-javascript/pull/17428))**

This PR enhances the Hono integration by adding comprehensive handler instrumentation, error handling capabilities.

- **feat(aws): Enable Lambda extension by default when using the Lamba layer ([#17684](https://github.com/getsentry/sentry-javascript/pull/17684))**

- **feat(browser): Add `setActiveSpanInBrowser` to set an active span in the browser ([#17714](https://github.com/getsentry/sentry-javascript/pull/17714))**

This PR adds a feature to the browser SDKs only: Making an inactive span active. We do this to enable use cases where having a span only being active in the callback is not practical.

### Other Changes

- fix(browser): Improve handling of `0` and `undefined` resource timing values ([#17751](https://github.com/getsentry/sentry-javascript/pull/17751))
- ref(nextjs): Display build compatibility warning for webpack ([#17746](https://github.com/getsentry/sentry-javascript/pull/17746))

<details>
<summary> <strong>Internal Changes</strong> </summary>

- docs: Reword changelog for google gen ai instrumentation ([#17753](https://github.com/getsentry/sentry-javascript/pull/17753))
- build: Add `@typescript-eslint/no-unnecessary-type-assertion` rule ([#17728](https://github.com/getsentry/sentry-javascript/pull/17728))
- build: Update TS target to `es2020` everywhere ([#17709](https://github.com/getsentry/sentry-javascript/pull/17709))
- chore: Add external contributor to CHANGELOG.md ([#17745](https://github.com/getsentry/sentry-javascript/pull/17745))

</details>

Work in this release was contributed by @Karibash. Thank you for your contribution!

## 10.14.0

### Important Changes

- **feat(cloudflare,vercel-edge): Add support for Google Gen AI instrumentation ([#17723](https://github.com/getsentry/sentry-javascript/pull/17723))**

The SDK now automatically instruments Google's Generative AI operations in Cloudflare Workers and Vercel Edge Runtime environments, providing insights into your AI operations.
The SDK now supports manually instrumenting Google's Generative AI operations in Cloudflare Workers and Vercel Edge Runtime environments, providing insights into your AI operations. You can use `const wrappedClient = Sentry.instrumentGoogleGenAIClient(genAiClient)` to get an instrumented client.

### Other Changes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ sentryTest('captures Breadcrumb for basic GET request', async ({ getLocalTestUrl
expect(eventData.exception?.values).toHaveLength(1);

expect(eventData?.breadcrumbs?.length).toBe(1);
expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'fetch',
type: 'http',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ sentryTest('captures Breadcrumb for basic GET request that uses request object',
expect(eventData.exception?.values).toHaveLength(1);

expect(eventData?.breadcrumbs?.length).toBe(1);
expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'fetch',
type: 'http',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ sentryTest('captures Breadcrumb for POST request', async ({ getLocalTestUrl, pag
expect(eventData.exception?.values).toHaveLength(1);

expect(eventData?.breadcrumbs?.length).toBe(1);
expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'fetch',
type: 'http',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ sentryTest('captures Breadcrumb with log level for 4xx response code', async ({
expect(eventData.exception?.values).toHaveLength(1);

expect(eventData?.breadcrumbs?.length).toBe(1);
expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'fetch',
type: 'http',
Expand Down Expand Up @@ -56,7 +56,7 @@ sentryTest('captures Breadcrumb with log level for 5xx response code', async ({
expect(eventData.exception?.values).toHaveLength(1);

expect(eventData?.breadcrumbs?.length).toBe(1);
expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'fetch',
type: 'http',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ sentryTest('captures Breadcrumb for basic GET request', async ({ getLocalTestUrl
expect(eventData.exception?.values).toHaveLength(1);

expect(eventData?.breadcrumbs?.length).toBe(1);
expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'xhr',
type: 'http',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ sentryTest('captures Breadcrumb for POST request', async ({ getLocalTestUrl, pag
expect(eventData.exception?.values).toHaveLength(1);

expect(eventData?.breadcrumbs?.length).toBe(1);
expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'xhr',
type: 'http',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ sentryTest('captures Breadcrumb with log level for 4xx response code', async ({
expect(eventData.exception?.values).toHaveLength(1);

expect(eventData?.breadcrumbs?.length).toBe(1);
expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'xhr',
type: 'http',
Expand Down Expand Up @@ -56,7 +56,7 @@ sentryTest('captures Breadcrumb with log level for 5xx response code', async ({
expect(eventData.exception?.values).toHaveLength(1);

expect(eventData?.breadcrumbs?.length).toBe(1);
expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'xhr',
type: 'http',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ sentryTest('should update breadcrumbs for GraphQL fetch requests', async ({ getL

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

expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'fetch',
type: 'http',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ sentryTest('should update breadcrumbs for GraphQL XHR requests', async ({ getLoc

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

expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'xhr',
type: 'http',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { sentryTest } from '../../../utils/fixtures';
import { getFirstSentryEnvelopeRequest } from '../../../utils/helpers';

sentryTest('Assigns web worker debug IDs when using webWorkerIntegration', async ({ getLocalTestUrl, page }) => {
const bundle = process.env.PW_BUNDLE as string | undefined;
const bundle = process.env.PW_BUNDLE;
if (bundle != null && !bundle.includes('esm') && !bundle.includes('cjs')) {
sentryTest.skip();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { expect } from '@playwright/test';
import type { Event, FeedbackEvent } from '@sentry/core';
import type { Event } from '@sentry/core';
import { sentryTest } from '../../../../utils/fixtures';
import { getMultipleSentryEnvelopeRequests } from '../../../../utils/helpers';

sentryTest('capture user feedback when captureException is called', async ({ getLocalTestUrl, page }) => {
const url = await getLocalTestUrl({ testDir: __dirname });

const data = (await getMultipleSentryEnvelopeRequests(page, 2, { url })) as (Event | FeedbackEvent)[];
const data = await getMultipleSentryEnvelopeRequests<Event>(page, 2, { url });

expect(data).toHaveLength(2);

const errorEvent = ('exception' in data[0] ? data[0] : data[1]) as Event;
const feedback = ('exception' in data[0] ? data[1] : data[0]) as FeedbackEvent;
const errorEvent = 'exception' in data[0] ? data[0] : data[1];
const feedback = 'exception' in data[0] ? data[1] : data[0];

expect(feedback.contexts).toEqual(
expect.objectContaining({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { expect } from '@playwright/test';
import type { Event, FeedbackEvent } from '@sentry/core';
import type { Event } from '@sentry/core';
import { sentryTest } from '../../../../utils/fixtures';
import { getMultipleSentryEnvelopeRequests } from '../../../../utils/helpers';

sentryTest('capture user feedback when captureMessage is called', async ({ getLocalTestUrl, page }) => {
const url = await getLocalTestUrl({ testDir: __dirname });

const data = (await getMultipleSentryEnvelopeRequests(page, 2, { url })) as (Event | FeedbackEvent)[];
const data = await getMultipleSentryEnvelopeRequests<Event>(page, 2, { url });

expect(data).toHaveLength(2);

const errorEvent = ('exception' in data[0] ? data[0] : data[1]) as Event;
const feedback = ('exception' in data[0] ? data[1] : data[0]) as FeedbackEvent;
const errorEvent = 'exception' in data[0] ? data[0] : data[1];
const feedback = 'exception' in data[0] ? data[1] : data[0];

expect(feedback.contexts).toEqual(
expect.objectContaining({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { sentryTest } from '../../../utils/fixtures';
import { envelopeRequestParser, shouldSkipTracingTest, waitForTransactionRequest } from '../../../utils/helpers';

sentryTest('makes a call to sentry.io to diagnose SDK connectivity', async ({ getLocalTestUrl, page }) => {
const bundle = process.env.PW_BUNDLE as string | undefined;
const bundle = process.env.PW_BUNDLE;
if (shouldSkipTracingTest() || !!bundle) {
// the CDN bundle doesn't export diagnoseSdkConnectivity. So skipping the test for bundles.
sentryTest.skip();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ sentryTest(
const outsideCtx = window as any;
requestAnimationFrame(function () {
// @ts-expect-error re-assigning this
resolve({ outsideCtx, requestAnimationFrameCtx: this as any });
resolve({ outsideCtx, requestAnimationFrameCtx: this });
});
});
})) as any;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ sentryTest(

const req0 = await transactionReq;

const envHeader = envelopeRequestParser(req0, 0) as EventEnvelopeHeaders;
const envHeader = envelopeRequestParser<EventEnvelopeHeaders>(req0, 0);
const replay = await getReplaySnapshot(page);

expect(replay.session?.id).toBeDefined();
Expand Down Expand Up @@ -96,7 +96,7 @@ sentryTest(

const req0 = await transactionReq;

const envHeader = envelopeRequestParser(req0, 0) as EventEnvelopeHeaders;
const envHeader = envelopeRequestParser<EventEnvelopeHeaders>(req0, 0);
const replay = await getReplaySnapshot(page);

expect(replay.session?.id).toBeDefined();
Expand Down Expand Up @@ -148,7 +148,7 @@ sentryTest(

const req0 = await transactionReq;

const envHeader = envelopeRequestParser(req0, 0) as EventEnvelopeHeaders;
const envHeader = envelopeRequestParser<EventEnvelopeHeaders>(req0, 0);
const replay = await getReplaySnapshot(page);

expect(replay.session?.id).toBeDefined();
Expand Down Expand Up @@ -191,7 +191,7 @@ sentryTest(

const req0 = await transactionReq;

const envHeader = envelopeRequestParser(req0, 0) as EventEnvelopeHeaders;
const envHeader = envelopeRequestParser<EventEnvelopeHeaders>(req0, 0);

const replay = await getReplaySnapshot(page);

Expand Down Expand Up @@ -235,7 +235,7 @@ sentryTest('should add replay_id to error DSC while replay is active', async ({

await page.evaluate('window._triggerError(1)');

const error1Header = envelopeRequestParser(await error1Req, 0) as EventEnvelopeHeaders;
const error1Header = envelopeRequestParser<EventEnvelopeHeaders>(await error1Req, 0);
const replay = await getReplaySnapshot(page);

expect(replay.session?.id).toBeDefined();
Expand All @@ -260,7 +260,7 @@ sentryTest('should add replay_id to error DSC while replay is active', async ({
await page.waitForFunction('!window.Replay.getReplayId();');
await page.evaluate('window._triggerError(2)');

const error2Header = envelopeRequestParser(await error2Req, 0) as EventEnvelopeHeaders;
const error2Header = envelopeRequestParser<EventEnvelopeHeaders>(await error2Req, 0);

expect(error2Header.trace).toBeDefined();
expect(error2Header.trace).toEqual({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ sentryTest('captures text request body', async ({ getLocalTestUrl, page, browser
expect(eventData.exception?.values).toHaveLength(1);

expect(eventData?.breadcrumbs?.length).toBe(1);
expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'fetch',
type: 'http',
Expand Down Expand Up @@ -114,7 +114,7 @@ sentryTest('captures JSON request body', async ({ getLocalTestUrl, page, browser
expect(eventData.exception?.values).toHaveLength(1);

expect(eventData?.breadcrumbs?.length).toBe(1);
expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'fetch',
type: 'http',
Expand Down Expand Up @@ -188,7 +188,7 @@ sentryTest('captures non-text request body', async ({ getLocalTestUrl, page, bro
expect(eventData.exception?.values).toHaveLength(1);

expect(eventData?.breadcrumbs?.length).toBe(1);
expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'fetch',
type: 'http',
Expand Down Expand Up @@ -258,7 +258,7 @@ sentryTest('captures text request body when matching relative URL', async ({ get
expect(eventData.exception?.values).toHaveLength(1);

expect(eventData?.breadcrumbs?.length).toBe(1);
expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'fetch',
type: 'http',
Expand Down Expand Up @@ -326,7 +326,7 @@ sentryTest('does not capture request body when URL does not match', async ({ get
expect(eventData.exception?.values).toHaveLength(1);

expect(eventData?.breadcrumbs?.length).toBe(1);
expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'fetch',
type: 'http',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ sentryTest('handles empty/missing request headers', async ({ getLocalTestUrl, pa
expect(eventData.exception?.values).toHaveLength(1);

expect(eventData?.breadcrumbs?.length).toBe(1);
expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'fetch',
type: 'http',
Expand Down Expand Up @@ -118,7 +118,7 @@ sentryTest('captures request headers as POJO', async ({ getLocalTestUrl, page, b
expect(eventData.exception?.values).toHaveLength(1);

expect(eventData?.breadcrumbs?.length).toBe(1);
expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'fetch',
type: 'http',
Expand Down Expand Up @@ -198,7 +198,7 @@ sentryTest('captures request headers on Request', async ({ getLocalTestUrl, page
expect(eventData.exception?.values).toHaveLength(1);

expect(eventData?.breadcrumbs?.length).toBe(1);
expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'fetch',
type: 'http',
Expand Down Expand Up @@ -277,7 +277,7 @@ sentryTest('captures request headers as Headers instance', async ({ getLocalTest
expect(eventData.exception?.values).toHaveLength(1);

expect(eventData?.breadcrumbs?.length).toBe(1);
expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'fetch',
type: 'http',
Expand Down Expand Up @@ -353,7 +353,7 @@ sentryTest('does not captures request headers if URL does not match', async ({ g
expect(eventData.exception?.values).toHaveLength(1);

expect(eventData?.breadcrumbs?.length).toBe(1);
expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'fetch',
type: 'http',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ sentryTest('captures request body size when body is sent', async ({ getLocalTest
expect(eventData.exception?.values).toHaveLength(1);

expect(eventData?.breadcrumbs?.length).toBe(1);
expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'fetch',
type: 'http',
Expand Down Expand Up @@ -124,7 +124,7 @@ sentryTest('captures request size from non-text request body', async ({ getLocal
expect(eventData.exception?.values).toHaveLength(1);

expect(eventData?.breadcrumbs?.length).toBe(1);
expect(eventData!.breadcrumbs![0]).toEqual({
expect(eventData.breadcrumbs![0]).toEqual({
timestamp: expect.any(Number),
category: 'fetch',
type: 'http',
Expand Down
Loading
Loading