From 1f0c7e582dab46ae1cecbcea89601bcb9473a173 Mon Sep 17 00:00:00 2001 From: Charly Gomez Date: Fri, 25 Sep 2026 16:21:42 +0200 Subject: [PATCH 1/3] docs(js): Document Prisma 8 support in prismaIntegration Prisma 8 is instrumented through diagnostics channels starting with SDK 11.1.0. Add it to the supported versions and note its span shape and limitations. Refs getsentry/sentry-javascript#24682 Co-Authored-By: Claude Opus 5.5 --- .../configuration/integrations/prisma.mdx | 20 ++++++++++++++++--- .../configuration/integrations/prisma.mdx | 8 +++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/docs/platforms/javascript/common/configuration/integrations/prisma.mdx b/docs/platforms/javascript/common/configuration/integrations/prisma.mdx index 1142dd1ac8d16..7fdbee6cc577d 100644 --- a/docs/platforms/javascript/common/configuration/integrations/prisma.mdx +++ b/docs/platforms/javascript/common/configuration/integrations/prisma.mdx @@ -11,7 +11,7 @@ Sentry supports tracing [Prisma ORM](https://www.prisma.io/) queries with the Pr The Prisma Integrations creates a spans for each query and reports to Sentry with relevant details inside the`description` if available. -This integration is enabled by default and supports Prisma versions 5, 6 & 7. In Prisma v5, you need to follow the instructions below to enable tracing. +This integration is enabled by default and supports Prisma versions 5, 6, 7 & 8. In Prisma v5, you need to follow the instructions below to enable tracing. If you'd like to learn how to modify your default integrations, visit the docs on Modifying Default Integrations. @@ -26,6 +26,20 @@ Sentry.init({ }); ``` +## Prisma Version 8 + +_Available since: `11.1.0`_ + +No configuration is required. Prisma 8 has no built-in tracing, so the SDK instruments it through diagnostics channels. If channel injection is disabled (`enableRuntimeChannelInjection: false` without build-time injection), no Prisma 8 spans are created. + +Each ORM call creates a `prisma:client:operation` span with the `pg` query spans nested underneath. `db.sql`, `db.raw`, and `groupBy` calls only create `pg` query spans. + + + +On Node.js 20, CommonJS apps only get `pg` query spans. + + + ## Prisma Version 5 To configure the integration for Prisma version 5, first add the `tracing` feature flag to the `generator` block of your Prisma schema: @@ -48,8 +62,8 @@ Sentry.init({ ## Supported Versions -- `prisma`: `5.x`, `6.x`, `7.x` +- `prisma`: `5.x`, `6.x`, `7.x`, `8.x` ## Learn More -For details on the span structure that Prisma's OpenTelemetry tracing produces (e.g., `prisma:client:operation`, `prisma:engine:db_query`), see the [Prisma trace output documentation](https://www.prisma.io/docs/orm/prisma-client/observability-and-logging/opentelemetry-tracing#trace-output). +For details on the span structure that Prisma's OpenTelemetry tracing produces in Prisma versions 5 to 7 (e.g., `prisma:client:operation`, `prisma:engine:db_query`), see the [Prisma trace output documentation](https://www.prisma.io/docs/orm/prisma-client/observability-and-logging/opentelemetry-tracing#trace-output). diff --git a/docs/platforms/javascript/guides/cloudflare/configuration/integrations/prisma.mdx b/docs/platforms/javascript/guides/cloudflare/configuration/integrations/prisma.mdx index c6f8ae2472a07..b9598a2130f00 100644 --- a/docs/platforms/javascript/guides/cloudflare/configuration/integrations/prisma.mdx +++ b/docs/platforms/javascript/guides/cloudflare/configuration/integrations/prisma.mdx @@ -18,7 +18,7 @@ Sentry.init({ }); ``` -This integration supports Prisma versions 5, 6, and 7. In Prisma v5, you also need to add the `tracing` preview feature to the `generator` block of your Prisma schema: +This integration supports Prisma versions 5, 6, 7, and 8. In Prisma v5, you also need to add the `tracing` preview feature to the `generator` block of your Prisma schema: ```txt {tabTitle: Prisma Schema} {filename: schema.prisma} {3} generator client { @@ -27,10 +27,12 @@ generator client { } ``` +Prisma 8 support requires SDK version `11.1.0` or higher. Prisma 8 has no built-in tracing, so the SDK instruments it through diagnostics channels. If channel injection is disabled (`enableRuntimeChannelInjection: false` without build-time injection), no Prisma 8 spans are created. Each ORM call creates a `prisma:client:operation` span with the `pg` query spans nested underneath. `db.sql`, `db.raw`, and `groupBy` calls only create `pg` query spans. + ## Supported Versions -- `prisma`: `5.x`, `6.x`, `7.x` +- `prisma`: `5.x`, `6.x`, `7.x`, `8.x` ## Learn More -For details on the span structure that Prisma's OpenTelemetry tracing produces (e.g., `prisma:client:operation`, `prisma:engine:db_query`), see the [Prisma trace output documentation](https://www.prisma.io/docs/orm/prisma-client/observability-and-logging/opentelemetry-tracing#trace-output). +For details on the span structure that Prisma's OpenTelemetry tracing produces in Prisma versions 5 to 7 (e.g., `prisma:client:operation`, `prisma:engine:db_query`), see the [Prisma trace output documentation](https://www.prisma.io/docs/orm/prisma-client/observability-and-logging/opentelemetry-tracing#trace-output). From ae8a34e7f1acdb19a4ee67d26c5591fd3553068e Mon Sep 17 00:00:00 2001 From: "sentry-junior[bot]" <264270552+sentry-junior[bot]@users.noreply.github.com> Date: Fri, 25 Sep 2026 14:42:10 +0000 Subject: [PATCH 2/3] fix(api): Escape numeric comparisons before compiling MDX OpenAPI descriptions allow literal less-than comparisons, but MDX treats them as malformed tags. Escape comparisons in prose without changing code examples or HTML so the custom inbound filter API pages can build. Co-Authored-By: Charly Gomez --- .../apiPage/escapeComparisons.test.ts | 40 +++++++++++++++++++ src/components/apiPage/escapeComparisons.ts | 29 ++++++++++++++ src/components/apiPage/index.tsx | 2 + 3 files changed, 71 insertions(+) create mode 100644 src/components/apiPage/escapeComparisons.test.ts create mode 100644 src/components/apiPage/escapeComparisons.ts diff --git a/src/components/apiPage/escapeComparisons.test.ts b/src/components/apiPage/escapeComparisons.test.ts new file mode 100644 index 0000000000000..1dc974c44e0d0 --- /dev/null +++ b/src/components/apiPage/escapeComparisons.test.ts @@ -0,0 +1,40 @@ +import {compile} from '@mdx-js/mdx'; +import {describe, expect, it} from 'vitest'; + +import {escapeComparisons} from './escapeComparisons'; + +describe('escapeComparisons', () => { + it('makes numeric comparisons in OpenAPI prose valid MDX', async () => { + const source = + 'Conditions are combined with AND: an event must match every condition to be filtered out. ' + + 'There is no OR between conditions, so e.g. two release conditions can express a range (>2 AND <4). ' + + "To broaden matching, widen a condition's values or add separate filters."; + await expect(compile(source)).rejects.toThrow('Unexpected character `4`'); + const escaped = escapeComparisons(source); + expect(escaped).toBe(source.replace('<4', '<4')); + await expect(compile(escaped)).resolves.toBeDefined(); + }); + + it('escapes multiple text nodes without shifting their offsets', () => { + expect(escapeComparisons('Use **<4** and [<10](/example/).')).toBe( + 'Use **<4** and [<10](/example/).' + ); + }); + + it.each([ + '`<4`', + '```js\nx <4\n```', + ' x <4\n', + 'Example', + '[Example](/example/ "<4")', + String.raw`Already escaped: \<4 and <4`, + ])('preserves code, HTML, links, and existing escapes: %s', source => { + expect(escapeComparisons(source)).toBe(source); + }); + + it('escapes comparisons after an escaped backslash', async () => { + const escaped = escapeComparisons(String.raw`Value \\<4`); + expect(escaped).toBe(String.raw`Value \\<4`); + await expect(compile(escaped)).resolves.toBeDefined(); + }); +}); diff --git a/src/components/apiPage/escapeComparisons.ts b/src/components/apiPage/escapeComparisons.ts new file mode 100644 index 0000000000000..6bb1831d3006e --- /dev/null +++ b/src/components/apiPage/escapeComparisons.ts @@ -0,0 +1,29 @@ +import {fromMarkdown} from 'mdast-util-from-markdown'; +import {visit} from 'unist-util-visit'; + +// OpenAPI descriptions are Markdown, where `<4` is text, not an MDX tag. +// Only escape prose so code examples, link destinations, and HTML stay intact. +export function escapeComparisons(source: string): string { + if (!/<\d/.test(source)) { + return source; + } + const replacements: {start: number; end: number; value: string}[] = []; + visit(fromMarkdown(source), 'text', node => { + const start = node.position?.start.offset; + const end = node.position?.end.offset; + if (start === undefined || end === undefined) { + return; + } + const text = source.slice(start, end); + const value = text.replace(/(\\*)<(?=\d)/g, (match, slashes: string) => + slashes.length % 2 ? match : `${slashes}<` + ); + if (value !== text) { + replacements.push({start, end, value}); + } + }); + for (const {start, end, value} of replacements.reverse()) { + source = source.slice(0, start) + value + source.slice(end); + } + return source; +} diff --git a/src/components/apiPage/index.tsx b/src/components/apiPage/index.tsx index 3599b95e160f3..737c90117563d 100644 --- a/src/components/apiPage/index.tsx +++ b/src/components/apiPage/index.tsx @@ -11,6 +11,7 @@ import remarkCodeTitles from 'sentry-docs/remark-code-title'; import {ApiExamples} from '../apiExamples/apiExamples'; import {DocPage} from '../docPage'; import {SmartLink} from '../smartLink'; +import {escapeComparisons} from './escapeComparisons'; function Params({params}) { return ( @@ -89,6 +90,7 @@ function cssToObj(css) { } async function parseMarkdown(source: string): Promise { + source = escapeComparisons(source); // Source uses string styles, but MDX requires object styles. source = source.replace(/style="([^"]+)"/g, (_, style) => { return `style={${JSON.stringify(cssToObj(style))}}`; From 0d7b50e4d8a48141049db0474f15578df893cdd2 Mon Sep 17 00:00:00 2001 From: "sentry-junior[bot]" <264270552+sentry-junior[bot]@users.noreply.github.com> Date: Fri, 25 Sep 2026 14:46:14 +0000 Subject: [PATCH 3/3] Revert "fix(api): Escape numeric comparisons before compiling MDX" This reverts commit ae8a34e7f1acdb19a4ee67d26c5591fd3553068e. Co-Authored-By: Charly Gomez --- .../apiPage/escapeComparisons.test.ts | 40 ------------------- src/components/apiPage/escapeComparisons.ts | 29 -------------- src/components/apiPage/index.tsx | 2 - 3 files changed, 71 deletions(-) delete mode 100644 src/components/apiPage/escapeComparisons.test.ts delete mode 100644 src/components/apiPage/escapeComparisons.ts diff --git a/src/components/apiPage/escapeComparisons.test.ts b/src/components/apiPage/escapeComparisons.test.ts deleted file mode 100644 index 1dc974c44e0d0..0000000000000 --- a/src/components/apiPage/escapeComparisons.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import {compile} from '@mdx-js/mdx'; -import {describe, expect, it} from 'vitest'; - -import {escapeComparisons} from './escapeComparisons'; - -describe('escapeComparisons', () => { - it('makes numeric comparisons in OpenAPI prose valid MDX', async () => { - const source = - 'Conditions are combined with AND: an event must match every condition to be filtered out. ' + - 'There is no OR between conditions, so e.g. two release conditions can express a range (>2 AND <4). ' + - "To broaden matching, widen a condition's values or add separate filters."; - await expect(compile(source)).rejects.toThrow('Unexpected character `4`'); - const escaped = escapeComparisons(source); - expect(escaped).toBe(source.replace('<4', '<4')); - await expect(compile(escaped)).resolves.toBeDefined(); - }); - - it('escapes multiple text nodes without shifting their offsets', () => { - expect(escapeComparisons('Use **<4** and [<10](/example/).')).toBe( - 'Use **<4** and [<10](/example/).' - ); - }); - - it.each([ - '`<4`', - '```js\nx <4\n```', - ' x <4\n', - 'Example', - '[Example](/example/ "<4")', - String.raw`Already escaped: \<4 and <4`, - ])('preserves code, HTML, links, and existing escapes: %s', source => { - expect(escapeComparisons(source)).toBe(source); - }); - - it('escapes comparisons after an escaped backslash', async () => { - const escaped = escapeComparisons(String.raw`Value \\<4`); - expect(escaped).toBe(String.raw`Value \\<4`); - await expect(compile(escaped)).resolves.toBeDefined(); - }); -}); diff --git a/src/components/apiPage/escapeComparisons.ts b/src/components/apiPage/escapeComparisons.ts deleted file mode 100644 index 6bb1831d3006e..0000000000000 --- a/src/components/apiPage/escapeComparisons.ts +++ /dev/null @@ -1,29 +0,0 @@ -import {fromMarkdown} from 'mdast-util-from-markdown'; -import {visit} from 'unist-util-visit'; - -// OpenAPI descriptions are Markdown, where `<4` is text, not an MDX tag. -// Only escape prose so code examples, link destinations, and HTML stay intact. -export function escapeComparisons(source: string): string { - if (!/<\d/.test(source)) { - return source; - } - const replacements: {start: number; end: number; value: string}[] = []; - visit(fromMarkdown(source), 'text', node => { - const start = node.position?.start.offset; - const end = node.position?.end.offset; - if (start === undefined || end === undefined) { - return; - } - const text = source.slice(start, end); - const value = text.replace(/(\\*)<(?=\d)/g, (match, slashes: string) => - slashes.length % 2 ? match : `${slashes}<` - ); - if (value !== text) { - replacements.push({start, end, value}); - } - }); - for (const {start, end, value} of replacements.reverse()) { - source = source.slice(0, start) + value + source.slice(end); - } - return source; -} diff --git a/src/components/apiPage/index.tsx b/src/components/apiPage/index.tsx index 737c90117563d..3599b95e160f3 100644 --- a/src/components/apiPage/index.tsx +++ b/src/components/apiPage/index.tsx @@ -11,7 +11,6 @@ import remarkCodeTitles from 'sentry-docs/remark-code-title'; import {ApiExamples} from '../apiExamples/apiExamples'; import {DocPage} from '../docPage'; import {SmartLink} from '../smartLink'; -import {escapeComparisons} from './escapeComparisons'; function Params({params}) { return ( @@ -90,7 +89,6 @@ function cssToObj(css) { } async function parseMarkdown(source: string): Promise { - source = escapeComparisons(source); // Source uses string styles, but MDX requires object styles. source = source.replace(/style="([^"]+)"/g, (_, style) => { return `style={${JSON.stringify(cssToObj(style))}}`;