public final void showError(@NotNull String message, @NotNull Throwable e) {
    if (getProject().isDisposed()) {
      return;
    }

    while (e instanceof InvocationTargetException) {
      if (e.getCause() == null) {
        break;
      }
      e = e.getCause();
    }

    ErrorInfo info = new ErrorInfo();
    info.myMessage = info.myDisplayMessage = message;
    info.myThrowable = e;
    configureError(info);

    if (info.myShowMessage) {
      showErrorPage(info);
    }
    if (info.myShowLog) {
      LOG.error(
          LogMessageEx.createEvent(
              info.myDisplayMessage,
              info.myMessage + "\n" + ExceptionUtil.getThrowableText(info.myThrowable),
              new Attachment(myFile)));
    } else {
      LOG.info(info.myDisplayMessage + "\n" + info.myMessage, info.myThrowable);
    }
  }
  // returns list of resolved files if updated successfully, or null if write action or dumb mode
  // started
  private int[] processFile(
      @NotNull final VirtualFile file, int fileId, @NotNull final ProgressIndicator indicator) {
    final TIntHashSet forward;
    try {
      forward = calcForwardRefs(file, indicator);
    } catch (IndexNotReadyException e) {
      return null;
    } catch (ApplicationUtil.CannotRunReadActionException e) {
      return null;
    } catch (ProcessCanceledException e) {
      throw e;
    } catch (Exception e) {
      log(ExceptionUtil.getThrowableText(e));
      flushLog();
      return null;
    }

    int[] forwardIds = forward.toArray();
    fileIsResolved.set(fileId);
    logf(
        "  ---- " + file.getPresentableUrl() + " processed. forwardIds: " + toVfString(forwardIds));
    for (Listener listener : myListeners) {
      listener.fileResolved(file);
    }
    return forwardIds;
  }
 public static void error(
     @NotNull Logger logger,
     @NotNull String message,
     @NotNull Throwable cause,
     @NotNull String... attachmentText) {
   StringBuilder detailsBuffer = new StringBuilder();
   for (String detail : attachmentText) {
     detailsBuffer.append(detail).append(",");
   }
   if (attachmentText.length > 0 && detailsBuffer.length() > 0) {
     detailsBuffer.setLength(detailsBuffer.length() - 1);
   }
   Attachment attachment =
       detailsBuffer.length() > 0
           ? new Attachment("current-context.txt", detailsBuffer.toString())
           : null;
   logger.error(
       createEvent(message, ExceptionUtil.getThrowableText(cause), null, null, attachment));
 }
 // TODO this is to be removed when tags will be supported by the GitRepositoryReader
 private Collection<? extends VcsRef> readTags(@NotNull VirtualFile root) throws VcsException {
   GitSimpleHandler tagHandler = new GitSimpleHandler(myProject, root, GitCommand.LOG);
   tagHandler.setSilent(true);
   tagHandler.addParameters(
       "--tags", "--no-walk", "--format=%H%d" + GitLogParser.RECORD_START_GIT, "--decorate=full");
   String out = tagHandler.run();
   Collection<VcsRef> refs = new ArrayList<VcsRef>();
   try {
     for (String record : out.split(GitLogParser.RECORD_START)) {
       if (!StringUtil.isEmptyOrSpaces(record)) {
         refs.addAll(new RefParser(myVcsObjectsFactory).parseCommitRefs(record.trim(), root));
       }
     }
   } catch (Exception e) {
     LOG.error(
         "Error during tags parsing",
         new Attachment("stack_trace.txt", ExceptionUtil.getThrowableText(e)),
         new Attachment("git_output.txt", out));
   }
   return refs;
 }