import { CallSite , callSiteToString } from '../types/CallSite' ; export interface Detail { callSite : string ; callContext : string | null ; asString : string ; unmappedStack : string [ ] ; doc : string | null ; causeAsString : string | undefined ; causeStack : string | undefined ; } export interface ErrorWithDoc extends Error { errorDoc : string ; callContext : string ; } export function originalError ( e ) { if ( ( e as ErrorWithOriginalError ) . originalError !== undefined ) { return originalError ( ( e as ErrorWithOriginalError ) . originalError ) ; } else { return e ; } interface ErrorWithOriginalError extends Error { originalError : Error ; } } export interface TestScriptErrorMapper { isScriptError ? ( error ) : boolean ; liftError ? ( error ) : TestScriptError ; maybeLiftError ? ( error ) : Error ; filterAndUnMapStack ? ( stack ) : string [ ] ; } export class TestScriptError extends Error { public stackWhenThrown : string ; constructor ( message , originalStack , public callSite , public unmappedStack , public originalError ) { super ( message ) ; this . stackWhenThrown = this . stack || '' ; this . stack = originalStack ; this . message = message ; } get hasDoc ( ) : boolean { return ( this . originalError as ErrorWithDoc ) . errorDoc !== undefined ; } get errorDoc ( ) : string | null { if ( ( this . originalError as ErrorWithDoc ) . errorDoc !== undefined ) { return ( this . originalError as ErrorWithDoc ) . errorDoc ; } else { return null ; } } get callContext ( ) : string | null { if ( ( this . originalError as ErrorWithDoc ) . callContext !== undefined ) { return ( this . originalError as ErrorWithDoc ) . callContext ; } else { return null ; } } get cause ( ) : Error { return originalError ( this . originalError ) ; } toDetailObject ( includeVerbose = false ) { const output = { callSite : this . callSiteString ( ) , callContext : this . callContext , asString : this . toString ( ) , unmappedStack : this . unmappedStack , doc : this . errorDoc , causeAsString : undefined , causeStack : undefined , } ; if ( includeVerbose ) { output . causeAsString = this . cause . toString ( ) ; output . causeStack = this . cause . stack ; } return output ; } toStringNodeFormat ( ) { return this . callSiteString ( ) + '\n\n' + this . toString ( ) + '\n' + this . unmappedStack . join ( '\n' ) ; } toVerboseString ( ) { const baseString = this . toStringNodeFormat ( ) ; return ( baseString + '\n\nVerbose detail:\ncause.toString():\n' + this . cause . toString ( ) + '\ncause.stack:\n' + this . cause . stack ) ; } callSiteString ( ) { return callSiteToString ( this . callSite ) ; } toJSON ( ) { const { message , stackWhenThrown : stack } = this ; return { message , stack , } ; } }