Code coverage report for core/src/errors/circuit/command.ts

Statements: 12.5% (3 / 24)      Branches: 0% (0 / 10)      Functions: 0% (0 / 6)      Lines: 13.64% (3 / 22)      Ignored: none     

All files » core/src/errors/circuit/ » command.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 601 1                                       1                                                                            
import {logger, MSG_FMT} from '../../internal/log';
import {Providers} from '../../providers';
 
 
export interface Command<T> {
  execute(...args: unknown[]): Promise<T>;
}
 
export interface CommandOptions {
  name: string;
 
  run<T>(...args: unknown[]): Promise<T>;
}
 
export interface CommandFactory {
  group?: string;
 
  build<T>(options: CommandOptions): Command<T>;
}
 
 
export function CircuitBreaker(options: CommandOptions, commandFactory?: CommandFactory) {
 
  return function (target: Record<string, any>, propertyKey: string | symbol, descriptor: PropertyDescriptor): void {
    const log = logger('@CircuitBreaker');
    log.debug(MSG_FMT.annotatingMethod, target.constructor.name, propertyKey, 'LogTime', options);
    const original = descriptor.value;
    descriptor.value = function circuitBreaker(...args: unknown[]): unknown {
 
      const factory = commandFactory ? commandFactory : Providers.provide<CommandFactory>('CommandFactory');
      let result;
 
      if (factory) {
        options.run = <T>(): Promise<T> => {
          let result;
          try {
            const applied = original.apply(this, args);
            if (applied instanceof Promise) {
              result = applied;
            } else {
              result = new Promise((res) => res(applied));
            }
          } catch (error) {
            result = new Promise((res, rej) => rej(error));
          }
          return result;
        };
 
        const command = factory?.build(options);
        result = command.execute(...args);
      } else {
        // result = original.apply(target, args);
        throw new Error(`Decorator @CircuitBreaker used on method [${target.constructor.name}.${String(propertyKey)}()] without a command factory configured! Make sure to call setCommandFactory().`);
      }
 
      return result;
    };
  }
}