Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
integrations: [Sentry.browserTracingIntegration(), Sentry.supabaseIntegration({ supabaseClient })],
tracesSampleRate: 1.0,
sendDefaultPii: true,
});

// Simulate database operations
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,37 +57,16 @@ test('Sends client-side Supabase db-operation spans and breadcrumbs to Sentry',

const transactionEvent = await pageloadTransactionPromise;

expect(transactionEvent.spans).toContainEqual(
expect.objectContaining({
description: 'select(*) filter(order, asc) from(todos)',
op: 'db',
data: expect.objectContaining({
'db.operation': 'select',
'db.query': ['select(*)', 'filter(order, asc)'],
'db.system': 'postgresql',
'sentry.op': 'db',
'sentry.origin': 'auto.db.supabase',
}),
parent_span_id: expect.stringMatching(/[a-f0-9]{16}/),
span_id: expect.stringMatching(/[a-f0-9]{16}/),
start_timestamp: expect.any(Number),
status: 'ok',
timestamp: expect.any(Number),
trace_id: expect.stringMatching(/[a-f0-9]{32}/),
origin: 'auto.db.supabase',
}),
);

expect(transactionEvent.spans).toContainEqual({
// Client uses default sendDefaultPii: false — URL filters and bodies are not attached to spans/breadcrumbs.
const redactedSelectSpan = expect.objectContaining({
description: '[redacted] from(todos)',
op: 'db',
data: expect.objectContaining({
'db.operation': 'select',
'db.query': ['select(*)', 'filter(order, asc)'],
'db.system': 'postgresql',
'sentry.op': 'db',
'sentry.origin': 'auto.db.supabase',
}),
description: 'select(*) filter(order, asc) from(todos)',
op: 'db',
parent_span_id: expect.stringMatching(/[a-f0-9]{16}/),
span_id: expect.stringMatching(/[a-f0-9]{16}/),
start_timestamp: expect.any(Number),
Expand All @@ -97,20 +76,26 @@ test('Sends client-side Supabase db-operation spans and breadcrumbs to Sentry',
origin: 'auto.db.supabase',
});

expect(transactionEvent.spans).toContainEqual(redactedSelectSpan);

const selectSpan = transactionEvent.spans?.find(
(s: { description?: string }) => s.description === '[redacted] from(todos)',
);
expect(selectSpan).toBeDefined();
expect(selectSpan!.data).not.toHaveProperty('db.query');

expect(transactionEvent.breadcrumbs).toContainEqual({
timestamp: expect.any(Number),
type: 'supabase',
category: 'db.select',
message: 'select(*) filter(order, asc) from(todos)',
data: expect.any(Object),
message: '[redacted] from(todos)',
});

expect(transactionEvent.breadcrumbs).toContainEqual({
timestamp: expect.any(Number),
type: 'supabase',
category: 'db.insert',
message: 'insert(...) select(*) from(todos)',
data: expect.any(Object),
message: 'insert(...) [redacted] from(todos)',
});
});

Expand Down
22 changes: 13 additions & 9 deletions packages/core/src/integrations/supabase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable max-lines */
import { addBreadcrumb } from '../breadcrumbs';
import { getClient } from '../currentScopes';
import { DEBUG_BUILD } from '../debug-build';
import { captureException } from '../exports';
import { defineIntegration } from '../integration';
Expand Down Expand Up @@ -361,12 +362,15 @@ function instrumentPostgRESTFilterBuilder(PostgRESTFilterBuilder: PostgRESTFilte
}
}

const sendDefaultPii = Boolean(getClient()?.getOptions().sendDefaultPii);

// Adding operation to the beginning of the description if it's not a `select` operation
// For example, it can be an `insert` or `update` operation but the query can be `select(...)`
// For `select` operations, we don't need repeat it in the description
const description = `${operation === 'select' ? '' : `${operation}${body ? '(...) ' : ''}`}${queryItems.join(
' ',
)} from(${table})`;
const mutationPart = operation === 'select' ? '' : `${operation}${Object.keys(body).length ? '(...) ' : ''}`;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Body check change breaks array insert descriptions

Medium Severity

The condition for showing (...) in the span description changed from body ? to Object.keys(body).length ?, but the local body variable (line 358) is always Object.create(null) — always truthy but potentially empty. For array body inserts (e.g., .insert([{title: 'Test'}])), isPlainObject returns false for arrays, so body stays empty and Object.keys(body).length is 0. This removes the (...) marker from the description, breaking the existing browser integration test that expects 'insert(...) filter(columns, ) from(todos)'.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 32f9b58. Configure here.

const queryPart = sendDefaultPii ? queryItems.join(' ') : queryItems.length > 0 ? '[redacted]' : '';
const descriptionMiddle = [mutationPart.trimEnd(), queryPart].filter(Boolean).join(' ');
const description = descriptionMiddle ? `${descriptionMiddle} from(${table})` : `from(${table})`;

const attributes: Record<string, any> = {
'db.table': table,
Expand All @@ -379,11 +383,11 @@ function instrumentPostgRESTFilterBuilder(PostgRESTFilterBuilder: PostgRESTFilte
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'db',
};

if (queryItems.length) {
if (queryItems.length && sendDefaultPii) {
attributes['db.query'] = queryItems;
}

if (Object.keys(body).length) {
if (Object.keys(body).length && sendDefaultPii) {
attributes['db.body'] = body;
}

Expand Down Expand Up @@ -413,10 +417,10 @@ function instrumentPostgRESTFilterBuilder(PostgRESTFilterBuilder: PostgRESTFilte
}

const supabaseContext: Record<string, any> = {};
if (queryItems.length) {
if (queryItems.length && sendDefaultPii) {
supabaseContext.query = queryItems;
}
if (Object.keys(body).length) {
if (Object.keys(body).length && sendDefaultPii) {
supabaseContext.body = body;
}

Expand Down Expand Up @@ -444,11 +448,11 @@ function instrumentPostgRESTFilterBuilder(PostgRESTFilterBuilder: PostgRESTFilte

const data: Record<string, unknown> = {};

if (queryItems.length) {
if (queryItems.length && sendDefaultPii) {
data.query = queryItems;
}

if (Object.keys(body).length) {
if (Object.keys(body).length && sendDefaultPii) {
data.body = body;
}

Expand Down
Loading
Loading