import { Dedupe , RewriteFrames , Transaction } from "@sentry/integrations" ; import * as Sentry from "@sentry/react" ; import React , { FunctionComponent } from "react" ; import { ensureNoStartSlash , getOrigin } from "coral-common/utils" ; import supportedBrowsersRegExp from "coral-framework/helpers/supportedBrowsersRegExp" ; import { ErrorReport , ErrorReporter , ErrorReporterScope , User , } from "../reporter" ; import { FakeDebugTransport } from "./fakeDebugTransport" ; declare const __webpack_public_path__ ; /**
 * getAppFilename transforms a filename like http://localhost:8080/assets/js/embed.js to
 * app:///assets/js/embed.js for sentry.
 */ export function getAppFilename ( filename , location = window . location . toString ( ) , publicPath = __webpack_public_path__ ) { if ( ! filename . includes ( "/assets/" ) ) { return filename ; } if ( publicPath === "/" ) { const origin = getOrigin ( location ) ; if ( filename . includes ( origin ) ) { const pathname = new URL ( filename ) . pathname ; return `app:///static/${ ensureNoStartSlash ( pathname ) }` ; } } else if ( filename . startsWith ( publicPath ) ) { const remaining = filename . substr ( publicPath . length ) ; return `app:///static/${ ensureNoStartSlash ( remaining ) }` ; } return filename ; } export class SentryErrorReporter implements ErrorReporter { public readonly ErrorBoundary ? : FunctionComponent ; constructor ( reporterFeedbackPrompt , dsn , options = { } ) { const whitelistUrls = [ getOrigin ( window . location . toString ( ) ) ] ; if ( __webpack_public_path__ !== "/" ) { whitelistUrls . push ( __webpack_public_path__ ) ; } Sentry . init ( { dsn , release : `coral@${ process . env . TALK_VERSION }` , debug : Boolean ( options . offlineDebug ) , transport : options . offlineDebug ? FakeDebugTransport : undefined , whitelistUrls , beforeSend : ( event ) => { if ( location . search . indexOf ( "fbclid" ) !== - 1 ) { return null ; } if ( ! supportedBrowsersRegExp . test ( navigator . userAgent ) ) { return null ; } return event ; } , integrations : [ ... Sentry . defaultIntegrations . map ( ( i ) => { if ( process . env . NODE_ENV !== "production" && i . name === "Breadcrumbs" ) { return new Sentry . Integrations . Breadcrumbs ( { console : false } ) ; } return i ; } ) , new RewriteFrames ( { iteratee : ( frame ) => { if ( frame . filename ) { frame . filename = getAppFilename ( frame . filename ) ; } return frame ; } , } ) , ... ( process . env . NODE_ENV === "production" ? [ new Dedupe ( ) ] : [ ] ) , new Transaction ( ) , ] , } ) ; if ( reporterFeedbackPrompt ) { this . ErrorBoundary = function ErrorBoundary ( { children } ) { return ( < Sentry . ErrorBoundary showDialog > { children } < /Sentry.ErrorBoundary>); } ; } } public report ( err , scope = { } ) { if ( typeof err === "string" ) { err = new Error ( err ) ; } Sentry . setTag ( "domain" , window . location . host ) ; const contexts = { } ; if ( scope . componentStack ) { contexts . react = { componentStack : scope . componentStack , } ; } const id = Sentry . captureException ( err , { contexts , } ) ; if ( process . env . NODE_ENV !== "production" ) { console . error ( err ) ; } return { name : "sentry" , id } ; } private transformUser ( user ) { if ( ! user ) { return null ; } return { id : user . id , username : user . username || undefined , role : user . role , } ; } public setUser ( user ) { const transformed = this . transformUser ( user ) ; if ( process . env . NODE_ENV === "development" ) { console . debug ( "sentry set user" , transformed ) ; } Sentry . setUser ( transformed ) ; } }