import { AdtHTTP , session_types } from "./AdtHTTP" ; import { fullParse , isNativeError , isNumber , isObject , isString , xmlArray } from "./utilities" ; import axios , { AxiosResponse , AxiosError } from "axios" ; const ADTEXTYPEID = Symbol ( ) ; const CSRFEXTYPEID = Symbol ( ) ; const HTTPEXTYPEID = Symbol ( ) ; export enum SAPRC { Success = "S" , Info = "I" , Warning = "W" , Error = "E" , CriticalError = "A" , Exception = "X" } export interface ExceptionProperties { conflictText : string ; ideUser : string ; "com.sap.adt.communicationFramework.subType" : string ; "T100KEY-ID" : string ; "T100KEY-NO" : string ; } const isResponse = ( r ) : r is AxiosResponse => isObject ( r ) && ! ! r ?. status && isString ( r ?. statusText ) ; class AdtErrorException extends Error { get typeID ( ) : symbol { return ADTEXTYPEID ; } public static create ( resp , properties ) ; public static create ( err , properties , type , message , parent ? , namespace ? , localizedMessage ? , response ? ) ; public static create ( errOrResponse , properties , type ? , message ? , parent ? , namespace ? , localizedMessage ? , response ? ) { if ( ! isNumber ( errOrResponse ) ) { return this . create ( errOrResponse . status , properties , "" , errOrResponse . statusText || "Unknown error in adt client" , undefined , undefined , undefined , errOrResponse ) ; } else { return new AdtErrorException ( errOrResponse , properties , type ! , message ! , parent , namespace , localizedMessage , response ) ; } } constructor ( public readonly err , public readonly properties , public readonly type , public readonly message , public readonly parent ? , public readonly namespace ? , public readonly localizedMessage ? , public readonly response ? ) { super ( ) ; } } class AdtCsrfException extends Error { get typeID ( ) : symbol { return CSRFEXTYPEID ; } constructor ( public readonly message , public readonly parent ? ) { super ( ) ; } } class AdtHttpException extends Error { get typeID ( ) : symbol { return HTTPEXTYPEID ; } get code ( ) { const p = this . parent ; return ( p . response && p . response . status ) || 0 ; } get message ( ) { return this . parent . message ; } get name ( ) { return this . parent . name ; } constructor ( public readonly parent ) { super ( ) ; } } export type AdtException = AdtErrorException | AdtCsrfException | AdtHttpException ; export function isAdtError ( e ) { return ( e as AdtErrorException ) . typeID === ADTEXTYPEID ; } export function isCsrfError ( e ) { return ( e as AdtErrorException ) . typeID === CSRFEXTYPEID ; } export function isHttpError ( e ) { return ( e as AdtErrorException ) . typeID === HTTPEXTYPEID ; } export function isAdtException ( e ) { return isAdtError ( e ) || isCsrfError ( e ) || isHttpError ( e ) ; } const simpleError = ( response ) => adtException ( `Error ${ response . status }:${ response . statusText }` ) ; export function fromException_int ( errOrResp ) { try { if ( isResponse ( errOrResp ) || ( axios . isAxiosError ( errOrResp ) && errOrResp . response ) ) { const response = isResponse ( errOrResp ) ? errOrResp : errOrResp . response ! ; if ( ! response . data ) return simpleError ( response ) ; if ( response . status === 403 && response . headers [ "x-csrf-token" ] === "Required" ) return new AdtCsrfException ( response . data as string ) ; const raw = fullParse ( response . data as string ) ; const root = raw [ "exc:exception" ] ; if ( ! root ) return simpleError ( response ) ; const getf = ( base , idx ) => ( base ? base [ idx ] : "" ) ; const properties = { } ; xmlArray ( root , "properties" , "entry" ) . forEach ( ( p ) => { properties [ p [ "@_key" ] ] = `${ p [ "#text" ] }` . replace ( /^\s+/ , "" ) . replace ( /\s+$/ , "" ) ; } ) ; return new AdtErrorException ( response . status , properties , root . type [ "@_id" ] , root . message [ "#text" ] , undefined , getf ( root . namespace , "@_id" ) , getf ( root . localizedMessage , "#text" ) ) ; } else { const error = new AdtHttpException ( { name : errOrResp . name , message : `${ errOrResp . message } : ${ ( errOrResp ?. response ) ? errOrResp . response . data : '' }` , stack : errOrResp . stack } ) ; return error ; } } catch ( e ) { return isResponse ( errOrResp ) ? AdtErrorException . create ( errOrResp , { } ) : new AdtHttpException ( errOrResp ) ; } } export function fromException ( errOrResp ) { if ( isAdtException ( errOrResp ) ) return errOrResp ; if ( ! isResponse ( errOrResp ) && ( ! isNativeError ( errOrResp ) || ( isNativeError ( errOrResp ) && ! axios . isAxiosError ( errOrResp ) ) ) ) return AdtErrorException . create ( 500 , { } , "Unknown error" , `${ errOrResp }` ) ; return fromException_int ( errOrResp ) ; } export function adtException ( message ) { return new AdtErrorException ( 0 , { } , "" , message ) ; } export function ValidateObjectUrl ( url ) { if ( url . match ( /^\/sap\/bc\/adt\/[a-z]+\/[a-zA-Z%\$]?[\w%]+/ ) ) return ; throw new AdtErrorException ( 0 , { } , "BADOBJECTURL" , "Invalid Object URL:" + url ) ; } export function ValidateStateful ( h ) { if ( h . isStateful ) return ; throw new AdtErrorException ( 0 , { } , "STATELESS" , "This operation can only be performed in stateful mode" ) ; }