Files
supabase/apps/studio/sentry.client.config.ts
Alaister Young 2b419c70a1 chore: add usercentrics for consent management (#35384)
* chore: add usercentrics for consent management

* client component to make next.js happy

* address feedback

* move consent state to common

* fix import

* ensure page events are sent correctly

* add feature flag provider to ui library site

* fix ui lib 500 error

* skip in test env

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
Co-authored-by: Jordi Enric <jordi.err@gmail.com>
2025-05-05 13:18:48 +08:00

108 lines
4.7 KiB
TypeScript

// This file configures the initialization of Sentry on the client.
// The config you add here will be used whenever a users loads a page in their browser.
// https://docs.sentry.io/platforms/javascript/guides/nextjs/
import * as Sentry from '@sentry/nextjs'
import { hasConsented } from 'common'
import { IS_PLATFORM } from 'common/constants/environment'
import { match } from 'path-to-regexp'
// This is a workaround to ignore hCaptcha related errors.
function isHCaptchaRelatedError(event: Sentry.Event): boolean {
const errors = event.exception?.values ?? []
for (const error of errors) {
if (
error.value?.includes('is not a function') &&
error.stacktrace?.frames?.some((f) => f.filename === 'api.js')
) {
return true
}
}
return false
}
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_DSN,
// Setting this option to true will print useful information to the console while you're setting up Sentry.
debug: false,
beforeSend(event, hint) {
const consent = hasConsented()
if (IS_PLATFORM && consent) {
// Ignore invalid URL events for 99% of the time because it's using up a lot of quota.
const isInvalidUrlEvent = (hint.originalException as any)?.message?.includes(
`Failed to construct 'URL': Invalid URL`
)
if (isInvalidUrlEvent && Math.random() > 0.01) {
return null
}
return event
}
if (isHCaptchaRelatedError(event)) {
return null
}
return null
},
ignoreErrors: [
// Used exclusively in Monaco Editor.
'ResizeObserver',
's.getModifierState is not a function',
/^Uncaught NetworkError: Failed to execute 'importScripts' on 'WorkerGlobalScope'/,
// [Joshen] We currently use stripe-js for customers to save their credit card data
// I'm unable to reproduce this error on local, staging nor prod across chrome, safari or firefox
// Based on https://github.com/stripe/stripe-js/issues/26, it seems like this error is safe to ignore,
'Failed to load Stripe.js',
// [Joshen] This event started occurring after our fix in the org dropdown by reading the slug from
// the URL params instead of the store, but we cannot repro locally, staging nor on prod
// Safe to ignore since it's not a user-facing issue + we've not received any user feedback/report about it
// Ref: https://github.com/supabase/supabase/pull/9729
'The provided `href` (/org/[slug]/general) value is missing query values (slug)',
'The provided `href` (/org/[slug]/team) value is missing query values (slug)',
'The provided `href` (/org/[slug]/billing) value is missing query values (slug)',
'The provided `href` (/org/[slug]/invoices) value is missing query values (slug)',
// [Joshen] Seems to be from hcaptcha
"undefined is not an object (evaluating 'n.chat.setReady')",
"undefined is not an object (evaluating 'i.chat.setReady')",
// [Terry] When users paste in an embedded Github Gist
// Error thrown by `sql-formatter` lexer when given invalid input
// Original format: new Error(`Parse error: Unexpected "${text}" at line ${line} column ${col}`)
/^Parse error: Unexpected ".+" at line \d+ column \d+$/,
// [Joshen] IMO, should be caught on API if there's anything to handle - FE shouldn't dupe this alert
/504 Gateway Time-out/,
// [Joshen] This is the one caused by Google translate in the browser + 3rd party extensions
'Node.insertBefore: Child to insert before is not a child of this node',
// [Joshen] This one sprung up recently and I've no idea where this is coming from
'r.default.setDefaultLevel is not a function',
// [Joshen] Safe to ignore, it an error from the copyToClipboard
'The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.',
],
})
// Replace dynamic query param with a template text
// Support grouping sentry transaction
function standardiseRouterUrl(url: string) {
let finalUrl = url
const orgMatch = match('/org/:slug{/*path}', { decode: decodeURIComponent })
const orgMatchResult = orgMatch(finalUrl)
if (orgMatchResult) {
finalUrl = finalUrl.replace((orgMatchResult.params as any).slug, '[slug]')
}
const newOrgMatch = match('/new/:slug', { decode: decodeURIComponent })
const newOrgMatchResult = newOrgMatch(finalUrl)
if (newOrgMatchResult) {
finalUrl = finalUrl.replace((newOrgMatchResult.params as any).slug, '[slug]')
}
const projectMatch = match('/project/:ref{/*path}', { decode: decodeURIComponent })
const projectMatchResult = projectMatch(finalUrl)
if (projectMatchResult) {
finalUrl = finalUrl.replace((projectMatchResult.params as any).ref, '[ref]')
}
return finalUrl
}