import React from 'react' ; import { render } from 'react-dom' ; import * as Rx from 'rxjs' ; import { first , tap } from 'rxjs/operators' ; import { I18nStart } from '../i18n' ; import { InjectedMetadataSetup } from '../injected_metadata' ; import { FatalErrorsScreen } from './fatal_errors_screen' ; import { FatalErrorInfo , getErrorInfo } from './get_error_info' ; interface Deps { i18n : I18nStart ; injectedMetadata : InjectedMetadataSetup ; } public export interface FatalErrorsSetup { param error param source add : ( error : string | Error , source ? : string ) => never ; /**
     * An Observable that will emit whenever a fatal error is added with `add()`
     */ get$ : ( ) => Rx . Observable < FatalErrorInfo > ; } public export type FatalErrorsStart = FatalErrorsSetup ; interal export class FatalErrorsService { private readonly errorInfo$ = new Rx . ReplaySubject < FatalErrorInfo > ( ) ; private fatalErrors ? : FatalErrorsSetup ; param rootDomElement param onFirstErrorCb constructor ( private rootDomElement , private onFirstErrorCb ) { } public setup ( { i18n , injectedMetadata } ) { this . errorInfo$ . pipe ( first ( ) , tap ( ( ) => { this . onFirstErrorCb ( ) ; this . renderError ( injectedMetadata , i18n ) ; } ) ) . subscribe ( { error : ( error ) => { console . error ( 'Uncaught error in fatal error service internals' , error ) ; } , } ) ; this . fatalErrors = { add : ( error , source ? ) => { const errorInfo = getErrorInfo ( error , source ) ; this . errorInfo$ . next ( errorInfo ) ; if ( error instanceof Error ) { console . error ( error ) ; } throw error ; } , get$ : ( ) => { return this . errorInfo$ . asObservable ( ) ; } , } ; this . setupGlobalErrorHandlers ( this . fatalErrors ! ) ; return this . fatalErrors ! ; } public start ( ) { const { fatalErrors } = this ; if ( ! fatalErrors ) { throw new Error ( 'FatalErrorsService#setup() must be invoked before start.' ) ; } return fatalErrors ; } private renderError ( injectedMetadata , i18n ) { this . rootDomElement . textContent = '' ; const container = document . createElement ( 'div' ) ; this . rootDomElement . appendChild ( container ) ; render ( < i18n . Context > < FatalErrorsScreen buildNumber = { injectedMetadata . getOpenSearchDashboardsBuildNumber ( ) } opensearchDashboardsVersion = { injectedMetadata . getOpenSearchDashboardsVersion ( ) } errorInfo$ = { this . errorInfo$ } / > < /i18n.Context>, container); } private setupGlobalErrorHandlers ( fatalErrorsSetup ) { if ( window . addEventListener ) { window . addEventListener ( 'unhandledrejection' , function ( e ) { console . log ( `Detected an unhandled Promise rejection.\n${ e . reason }` ) ; } ) ; } } }