export type Values = E[keyof E]; export abstract class EngineError extends Error { static readonly errors = { ChannelError: 'ChannelError', JoinChannelError: 'JoinChannelError', CloseChannelError: 'CloseChannelError', UpdateChannelError: 'UpdateChannelError', NonceError: 'NonceError', StoreError: 'StoreError', OnchainError: 'OnchainError', PushMessageError: 'PushMessageError', } as const; abstract readonly type: Values; static readonly reasons: {[key: string]: string}; constructor( public readonly reason: Values, public readonly data: any = undefined ) { super(reason); } } // eslint-disable-next-line @typescript-eslint/ban-types function hasOwnProperty( obj: X, prop: Y ): obj is X & Record { // eslint-disable-next-line no-prototype-builtins return obj.hasOwnProperty(prop); } // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types export function isEngineError(error: any): error is EngineError { if (!error?.type) return false; if (!(typeof error.type === 'string' || error.type instanceof String)) return false; return hasOwnProperty(EngineError.errors, error.type); } export class PushMessageError extends EngineError { readonly type = EngineError.errors.PushMessageError; static readonly reasons = { genericPushMessageError: 'Error during pushMessage', } as const; constructor( reason: Values, public readonly data: {thisWalletVersion: string; payloadWalletVersion: string; cause: Error} ) { super(reason); } }