async handleFailedTask()

in marketing-analytics/activation/data-tasks-coordinator/src/task_manager.js [163:209]


  async handleFailedTask(taskLogId, taskLog, error) {
    const taskConfig = await this.taskConfigDao.load(taskLog.taskId);
    if (!taskConfig) {
      this.logger.warn(
        `Obsolete task: ${taskLog.taskId} in TaskLog[${taskLogId}].`);
      return [
        ErrorHandledStatus.FAILED,
        this.taskLogDao.saveErrorMessage(taskLogId,
          new Error(`Task[${taskLog.taskId}] does not exist any more.`)),
      ];
    }
    /**@type {!ErrorOptions} */
    const errorOptions = Object.assign({
      retryTimes: DEFAULT_RETRY_TIMES,
      ignoreError: false, // Error is not ignored by default.
    }, taskConfig.errorOptions);
    if (error instanceof RetryableError) {
      const retriedTimes = taskLog[FIELD_NAMES.RETRIED_TIMES] || 0;
      if (retriedTimes < errorOptions.retryTimes) {
        // Change TaskLog status to 'RETRY'.
        // The two invokers of this function ('StatusCheckTask' and Sentinel)
        // will send a 'finish' task message when they receive
        // 'ErrorHandledStatus.RETRIED'.
        // The 'finish' message will then trigger next Sentinel execution, which
        // will restart (not finish) the task with the 'RETRY' status.
        return [
          ErrorHandledStatus.RETRIED,
          this.taskLogDao.merge({
            status: TaskLogStatus.RETRY,
            [FIELD_NAMES.RETRIED_TIMES]: retriedTimes + 1,
          }, taskLogId),
        ];
      }
      this.logger.info(
        'Reached the maximum retry times, continue to mark this task failed.');
    }
    if (errorOptions.ignoreError !== true) {
      return [
        ErrorHandledStatus.FAILED,
        this.taskLogDao.saveErrorMessage(taskLogId, error),
      ];
    }
    return [
      ErrorHandledStatus.IGNORED,
      this.taskLogDao.saveErrorMessage(taskLogId, error, true),
    ];
  }