| import { Breadcrumb } from '@sentry/browser'; |
|
|
| import VERSION from '../../version'; |
| import { DO_NOT_TRACK_ENABLED } from './utils'; |
|
|
| let _Sentry: typeof import('@sentry/browser'); |
|
|
| function getSentry(): Promise<typeof import('@sentry/browser')> { |
| return import( '@sentry/browser'); |
| } |
|
|
| let sentryInitialized = false; |
| let latestVersionPromise: Promise<string>; |
| const versionTimeout = 1 * 60 * 1000; |
| function getLatestVersion() { |
| if (!latestVersionPromise) { |
| latestVersionPromise = fetch('/version.txt') |
| .then(x => x.text()) |
| .catch(x => ''); |
|
|
| setTimeout(() => { |
| latestVersionPromise = undefined; |
| }, versionTimeout); |
| } |
|
|
| return latestVersionPromise; |
| } |
|
|
| export async function initialize(dsn: string) { |
| if (!DO_NOT_TRACK_ENABLED) { |
| _Sentry = await getSentry(); |
| const latestVersion = await getLatestVersion(); |
|
|
| if (VERSION !== latestVersion) { |
| |
| return Promise.resolve(); |
| } |
|
|
| sentryInitialized = true; |
|
|
| return _Sentry.init({ |
| dsn, |
| release: VERSION, |
| ignoreErrors: [ |
| 'Custom Object', |
| 'TypeScript Server Error', |
| /^Canceled$/, |
|
|
| |
| |
| /because a node with that id is already in the Store/, |
| /Node \d* was removed before its children\./, |
| /Cannot remove node \d* because no matching node was found in the Store\./, |
| /Cannot add child \d* to parent \d* because parent node was not found in the Store\./, |
| /Children cannot be added or removed during a reorder operation\./, |
| /Cannot reorder children for node/, |
|
|
| "undefined is not an object (evaluating 'window.__pad.performLoop')", |
| "Cannot assign to read only property 'exports' of object '#<Object>'", |
| ], |
| integrations: [ |
| new _Sentry.Integrations.TryCatch({ |
| setTimeout: false, |
| setInterval: false, |
| requestAnimationFrame: false, |
| }), |
| ], |
| allowUrls: [/https?:\/\/((uploads|www)\.)?codesandbox\.io/], |
| maxBreadcrumbs: 100, |
| |
| |
| |
| |
| denyUrls: ['codesandbox.editor.main.js', /.*\.csb\.app/], |
| beforeSend: (event, hint) => { |
| const exception = event?.exception?.values?.[0]; |
| const exceptionFrame = exception?.stacktrace?.frames?.[0]; |
| const filename = exceptionFrame?.filename; |
|
|
| if ( |
| !(hint.originalException instanceof Error) && |
| typeof hint.originalException === 'object' && |
| hint.originalException && |
| 'error' in hint.originalException |
| ) { |
| return null; |
| } |
|
|
| let errorMessage = |
| typeof hint.originalException === 'string' |
| ? hint.originalException |
| : hint.originalException?.message || exception.value; |
|
|
| if (typeof errorMessage !== 'string') { |
| errorMessage = ''; |
| } |
|
|
| if (filename) { |
| if ( |
| filename.includes('typescript-worker') && |
| errorMessage.includes('too much recursion') |
| ) { |
| |
| return null; |
| } |
|
|
| if ( |
| filename.endsWith('codesandbox.editor.main.js') || |
| filename.startsWith('/extensions/') |
| ) { |
| |
| |
| |
| return null; |
| } |
|
|
| if (filename.includes('tsserver.js')) { |
| |
| return null; |
| } |
| } |
|
|
| const customError = ((hint && (hint.originalException as any)) || {}) |
| .error; |
|
|
| if ( |
| customError && |
| errorMessage.startsWith('Non-Error exception captured') && |
| exception.mechanism.handled |
| ) { |
| |
| return null; |
| } |
|
|
| if (errorMessage.includes('Unexpected frame by generating stack.')) { |
| |
| return null; |
| } |
|
|
| return event; |
| }, |
| }); |
| } |
|
|
| return Promise.resolve(); |
| } |
|
|
| export const logBreadcrumb = (breadcrumb: Breadcrumb) => { |
| if (_Sentry && sentryInitialized) { |
| _Sentry.addBreadcrumb(breadcrumb); |
| } |
| }; |
|
|
| export const captureException = (err: Error) => { |
| if (_Sentry && sentryInitialized) { |
| return _Sentry.captureException(err); |
| } |
| return null; |
| }; |
|
|
| export const configureScope = cb => { |
| if (_Sentry && sentryInitialized) { |
| _Sentry.configureScope(cb); |
| } |
| }; |
|
|
| export const setUserId = userId => { |
| if (_Sentry && sentryInitialized) { |
| _Sentry.configureScope(scope => { |
| scope.setUser({ id: userId }); |
| }); |
| } |
| }; |
|
|
| export const resetUserId = () => { |
| if (_Sentry && sentryInitialized) { |
| _Sentry.configureScope(scope => { |
| scope.setUser({ id: undefined }); |
| }); |
| } |
| }; |
|
|