Suppress boring parts of the stack trace if something fails
Change-Id: Ib000d3de3d76cd9d9bb84839fd5d6e44a6ebdc49
diff --git a/src/main/java/com/googlesource/gerrit/plugins/supermanifest/SuperManifestRefUpdatedListener.java b/src/main/java/com/googlesource/gerrit/plugins/supermanifest/SuperManifestRefUpdatedListener.java
index 0d95224..19ad258 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/supermanifest/SuperManifestRefUpdatedListener.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/supermanifest/SuperManifestRefUpdatedListener.java
@@ -17,7 +17,6 @@
import static com.google.gerrit.reviewdb.client.RefNames.REFS_HEADS;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Preconditions;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.events.GitReferenceUpdatedListener;
import com.google.gerrit.extensions.events.LifecycleListener;
@@ -37,12 +36,13 @@
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
+import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
-import org.apache.http.client.utils.URIBuilder;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.RefNotFoundException;
@@ -159,7 +159,8 @@
srcRef = "";
} else {
if (!Repository.isValidRefName(destRef)) {
- throw new ConfigInvalidException(String.format("destination branch '%s' invalid", destRef));
+ throw new ConfigInvalidException(
+ String.format("destination branch '%s' invalid", destRef));
}
srcRef = cfg.getString(SECTION_NAME, name, "srcRef");
@@ -184,7 +185,6 @@
recordSubmoduleLabels = cfg.getBoolean(SECTION_NAME, name, "recordSubmoduleLabels", false);
-
try {
// http://foo/platform/manifest => http://foo/platform/
baseUri = new URI(srcRepoKey.toString()).resolve("");
@@ -268,7 +268,6 @@
wildcardDestinations.add(configEntry.destRepoKey.get());
}
-
sources.add(configEntry.srcRepoKey.get());
destinations.add(configEntry.destRepoKey.get());
@@ -290,7 +289,9 @@
public void stop() {}
@Override
- public void start() { updateConfiguration(); }
+ public void start() {
+ updateConfiguration();
+ }
/** for debugging. */
private String configurationToString() {
@@ -345,6 +346,11 @@
try {
update(c, event.getRefName());
} catch (IOException | GitAPIException e) {
+ // We only want the trace up to here. We could recurse into the exception, but this at least
+ // trims the very common jgit.gitrepo.RepoCommand.RemoteUnavailableException.
+ StackTraceElement here = Thread.currentThread().getStackTrace()[1];
+ e.setStackTrace(trimStack(e.getStackTrace(), here));
+
// We are in an asynchronously called listener, so there is no user action to give
// feedback to. We log the error, but it would be nice if we could surface these logs
// somewhere. Perhaps we could store these as commits in some special branch (but in
@@ -355,6 +361,24 @@
}
}
+ /**
+ * Remove boring stack frames. This retains the innermost frames up to and including the
+ * {@code class#method} passed in {@code ref}.
+ */
+ @VisibleForTesting
+ static StackTraceElement[] trimStack(StackTraceElement[] trace, StackTraceElement ref) {
+ List<StackTraceElement> trimmed = new ArrayList<>();
+ for (StackTraceElement e : trace) {
+ trimmed.add(e);
+ if (e.getClassName().equals(ref.getClassName())
+ && e.getMethodName().equals(ref.getMethodName())) {
+ break;
+ }
+ }
+
+ return trimmed.toArray(new StackTraceElement[trimmed.size()]);
+ }
+
private static class GerritIncludeReader implements ManifestParser.IncludedFileReader {
private final Repository repo;
private final String ref;
@@ -489,5 +513,4 @@
}
return name;
}
-
}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/supermanifest/SuperManifestIT.java b/src/test/java/com/googlesource/gerrit/plugins/supermanifest/SuperManifestIT.java
index 7a19516..d9dc131 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/supermanifest/SuperManifestIT.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/supermanifest/SuperManifestIT.java
@@ -27,6 +27,7 @@
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import java.net.URI;
+import java.util.Arrays;
import org.eclipse.jgit.internal.storage.dfs.InMemoryRepository;
import org.eclipse.jgit.junit.TestRepository;
import org.eclipse.jgit.lib.BlobBasedConfig;
@@ -165,6 +166,33 @@
assertThat(branch.file("project3").getContentType()).isEqualTo("x-git/gitlink; charset=UTF-8");
}
+ private void outer() {
+ inner();
+ }
+
+ private void inner() {
+ throw new IllegalStateException();
+ }
+
+ private void innerTest() {
+ try {
+ outer();
+ fail("should throw");
+ } catch (IllegalStateException e) {
+ StackTraceElement[] trimmed =
+ SuperManifestRefUpdatedListener.trimStack(
+ e.getStackTrace(), Thread.currentThread().getStackTrace()[1]);
+ String str = Arrays.toString(trimmed);
+ assertThat(str).doesNotContain("trimStackTrace");
+ assertThat(str).contains("innerTest");
+ }
+ }
+
+ @Test
+ public void trimStackTrace() throws Exception {
+ innerTest();
+ }
+
@Test
public void wildcardDestBranchWorks() throws Exception {
setupTestRepos("project");
@@ -365,13 +393,15 @@
public void testToRepoKey() {
URI base = URI.create("https://gerrit-review.googlesource.com");
assertThat(
- SuperManifestRefUpdatedListener.urlToRepoKey(base,
- "https://gerrit-review.googlesource.com/repo")).isEqualTo("repo");
+ SuperManifestRefUpdatedListener.urlToRepoKey(
+ base, "https://gerrit-review.googlesource.com/repo"))
+ .isEqualTo("repo");
assertThat(SuperManifestRefUpdatedListener.urlToRepoKey(base, "repo")).isEqualTo("repo");
assertThat(
- SuperManifestRefUpdatedListener.urlToRepoKey(
- URI.create("https://gerrit-review.googlesource.com/"),
- "https://gerrit-review.googlesource.com/repo")).isEqualTo("repo");
+ SuperManifestRefUpdatedListener.urlToRepoKey(
+ URI.create("https://gerrit-review.googlesource.com/"),
+ "https://gerrit-review.googlesource.com/repo"))
+ .isEqualTo("repo");
}
// TODO - should add tests for all the error handling in configuration parsing?