@RequiresSession
  public HostRoleCommandEntity findMostRecentFailure(Long requestId) {
    TypedQuery<HostRoleCommandEntity> query = entityManagerProvider.get().createNamedQuery(
        "HostRoleCommandEntity.findTasksByStatusesOrderByIdDesc", HostRoleCommandEntity.class);

    query.setParameter("requestId", requestId);
    query.setParameter("statuses", HostRoleStatus.STACK_UPGRADE_FAILED_STATUSES);
    List<HostRoleCommandEntity> results = query.getResultList();

    if (!results.isEmpty()) {
      HostRoleCommandEntity candidate = results.get(0);

      // Ensure that there are no other completed tasks in a future stage to avoid returning an old error.
      // During Express Upgrade, we can run multiple commands in the same stage, so it's possible to have
      // COMPLETED tasks in the failed task's stage.
      // During Rolling Upgrade, we run exactly one command per stage.
      TypedQuery<Number> numberAlreadyRanTasksInFutureStage = entityManagerProvider.get().createNamedQuery(
          "HostRoleCommandEntity.findNumTasksAlreadyRanInStage", Number.class);

      numberAlreadyRanTasksInFutureStage.setParameter("requestId", requestId);
      numberAlreadyRanTasksInFutureStage.setParameter("taskId", candidate.getTaskId());
      numberAlreadyRanTasksInFutureStage.setParameter("stageId", candidate.getStageId());
      numberAlreadyRanTasksInFutureStage.setParameter("statuses", HostRoleStatus.SCHEDULED_STATES);

      Number result = daoUtils.selectSingle(numberAlreadyRanTasksInFutureStage);
      if (result.longValue() == 0L) {
        return candidate;
      }
    }
    return null;
  }
During Rolling and Express Upgrade, want to bubble up the error of the most recent failure, i.e., greatest
task id, assuming that there are no other completed tasks after it.
@param requestId upgrade request id
@return Most recent task failure during stack upgrade, or null if one doesn't exist.
ambari-server/src/main/java/org/apache/ambari/server/orm/dao/HostRoleCommandDAO.java