{"size": 1493, "ext": "js", "max_stars_repo_path": "js/src/decorator/error.js", "max_stars_repo_name": "fingolfin/francy", "max_stars_repo_stars_event_min_datetime": null, "max_stars_repo_stars_event_max_datetime": null, "max_issues_repo_path": "js/src/decorator/error.js", "max_issues_repo_name": "fingolfin/francy", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "js/src/decorator/error.js", "max_forks_repo_name": "fingolfin/francy", "max_forks_repo_forks_event_min_datetime": null, "max_forks_repo_forks_event_max_datetime": null}
{"max_stars_count": null, "max_issues_count": null, "max_forks_count": null, "avg_line_length": 19.9066666667, "max_line_length": 87, "alphanum_fraction": 0.538513061}
import Logger from '../util/logger';

export default class ErrorDecorator {
  
  constructor() {
    this.logger = new Logger();
    this.onErrorFns = [];
    this.context = undefined;
    this.function = undefined;
    this.throw = false;
  }
  
  wrap(fn) {
    if (typeof fn !== 'function') throw Error(`[${fn}] is not a function!`);
    this.function = fn;
    return this;
  }

  withContext(ctx) {
    this.context = ctx;
    return this;
  }

  onErrorExec(fn) {
    if (typeof fn === 'function') {
      this.onErrorFns.push(fn);
    }
    return this;
  }
  
  onErrorThrow(t) {
    if(typeof (t) === 'boolean'){
      this.throw = t;
    }
    return this;
  }

  handle() {
    let result = undefined;
    try {
      result = this.function.apply(this.context, arguments);
      if (result && typeof result.then == 'function') {
        result = result.catch(error => {
          this._logEntry(error);
          this._runOnError();
        }).then(result => result);
      }
    } catch (error) {
      this._logEntry(error);
      this._runOnError();
      if (this.throw) {
        throw error;
      }
    }
    return result;
  }

  _runOnError() {
    this.onErrorFns.forEach(fn => {
      try {
        fn.call(this.context);
      } catch(error) {
        this._logEntry(error);
        if (this.throw) {
          throw error;
        }
      }
    });
  }

  _logEntry(error) {
    this.logger.info(`We can't do anything about this! An error occurred: [${error}]`);
  }

}