feat(studio) instrument sentry on table creation flow (#43673)

(working with @charislam @awaseem on this one)

## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

Per
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md):
- ✅ `pnpm --filter studio build`
- ✅ `pnpm test:prettier`
- ✅ `pnpm format`

## What kind of change does this PR introduce?

Instruments `studio` app's table creation flow with Sentry.

## What is the current behavior?

The table creation flow isn't instrumented in detail, which means we
have less visibility into understanding performance problems or errors
within this specific flow.

## What is the new behavior?

The table creation flow is instrumented in detail. This instrumentation
allows for Sentry dashboards like this one (created based on locally
generated Supabase data), to help monitor anything going wrong with this
critical flow:

<img width="1915" height="1131" alt="image"
src="https://github.com/user-attachments/assets/e2c5380e-7b00-41c1-9109-3ee4e47ff63b"
/>

---------

Co-authored-by: Ali Waseem <waseema393@gmail.com>
This commit is contained in:
Chris StavitskyandAli Waseem authored and GitHub committed 2026-03-16 09:57:43 -06:00
1 parent edf51dfd98
commit e217f747bd
4 files changed
+316 -195

No files matched your search

+32 -25
View File
@@ -1,3 +1,4 @@
import * as Sentry from '@sentry/nextjs'
import { PG_META_URL } from 'lib/constants/index'
import { constructHeaders } from '../apiHelpers'
import { PgMetaDatabaseError, databaseErrorSchema, WrappedResult } from './types'
@@ -31,30 +32,36 @@ export async function executeQuery<T = unknown>({
requestBody.parameters = parameters
}
const response = await fetch(`${PG_META_URL}/query`, {
method: 'POST',
headers: constructHeaders({
...headers,
'Content-Type': 'application/json',
'x-connection-encrypted': connectionStringEncrypted,
}),
body: JSON.stringify(requestBody),
return await Sentry.startSpan({ name: 'pg-meta.query', op: 'db.query' }, async (span) => {
const response = await fetch(`${PG_META_URL}/query`, {
method: 'POST',
headers: constructHeaders({
...headers,
'Content-Type': 'application/json',
'x-connection-encrypted': connectionStringEncrypted,
}),
body: JSON.stringify(requestBody),
})
try {
const result = await response.json()
if (!response.ok) {
const { message, code, formattedError } = databaseErrorSchema.parse(result)
span.setAttribute('db.error', 1)
span.setAttribute('db.status_code', response.status)
const error = new PgMetaDatabaseError(message, code, response.status, formattedError)
return { data: undefined, error }
}
span.setAttribute('db.status_code', response.status)
return { data: result, error: undefined }
} catch (error) {
span.setAttribute('db.error', 1)
if (error instanceof Error) {
return { data: undefined, error }
}
throw error
}
})
try {
const result = await response.json()
if (!response.ok) {
const { message, code, formattedError } = databaseErrorSchema.parse(result)
const error = new PgMetaDatabaseError(message, code, response.status, formattedError)
return { data: undefined, error }
}
return { data: result, error: undefined }
} catch (error) {
if (error instanceof Error) {
return { data: undefined, error }
}
throw error
}
}