/**
   * Fetch the output for a single task, store the result (or error message) in the model
   *
   * @param jobId id of the job containing this task
   * @param task task for which the output should be fetched
   * @param logMode one of {@link SchedulerServiceAsync#LOG_ALL}, {@link
   *     SchedulerServiceAsync#LOG_STDERR}, {@link SchedulerServiceAsync#LOG_STDOUT}
   */
  public void fetchTaskOutput(final String jobId, final Task task, final OutputMode logMode) {
    SchedulerServiceAsync scheduler = Scheduler.getSchedulerService();
    Request req =
        scheduler.getTaskOutput(
            LoginModel.getInstance().getSessionId(),
            "" + jobId,
            task.getName(),
            logMode,
            new AsyncCallback<String>() {
              public void onFailure(Throwable caught) {
                String msg = JSONUtils.getJsonErrorMessage(caught);
                // might be an exception
                try {
                  JSONObject json = JSONUtils.parseJSON(caught.getMessage()).isObject();
                  if (json.containsKey("stackTrace")) {
                    msg = json.get("stackTrace").isString().stringValue();
                    msg = msg.replace("\t", "&nbsp;&nbsp;&nbsp;&nbsp;");
                    msg = msg.replace("\n", "<br>");
                  }
                } catch (Throwable t) {
                  // not json
                }
                model.setTaskOutput(
                    jobId,
                    task,
                    "[" + task.getName() + "] <span style='color:red;'>" + msg + "</span>");
                LogModel.getInstance()
                    .logMessage(
                        "Failed to get output for task "
                            + task.getName()
                            + " in job "
                            + jobId /* + ": " + msg */);

                taskOutputRequests.remove("" + task.getId());
              }

              public void onSuccess(String result) {
                model.setTaskOutput(jobId, task, result);
                LogModel.getInstance()
                    .logMessage(
                        "Successfully fetched output for task "
                            + task.getName()
                            + " in job "
                            + jobId);

                taskOutputRequests.remove("" + task.getId());
              }
            });
    this.taskOutputRequests.put("" + task.getId(), req);
  }