Make exception types explicit

Change-Id: I0067a842ccb3748a33956e245307bf659c8c28ec
diff --git a/src/main/java/com/googlesource/gerrit/plugins/supermanifest/JiriManifestParser.java b/src/main/java/com/googlesource/gerrit/plugins/supermanifest/JiriManifestParser.java
index 1080bf4..96e0326 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/supermanifest/JiriManifestParser.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/supermanifest/JiriManifestParser.java
@@ -17,6 +17,7 @@
 import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.net.URI;
+import java.net.URISyntaxException;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.LinkedList;
@@ -27,11 +28,13 @@
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 import javax.xml.transform.stream.StreamSource;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.lib.Repository;
 
 class JiriManifestParser {
   public static JiriProjects getProjects(Repository repo, String ref, String manifest)
-      throws Exception {
+      throws ConfigInvalidException, IOException {
     Queue<String> q = new LinkedList<>();
     q.add(manifest);
     HashSet<String> processedFiles = new HashSet<>();
@@ -43,9 +46,14 @@
         continue;
       }
       processedFiles.add(file);
-      JiriManifest m = parseManifest(repo, ref, file);
+      JiriManifest m;
+      try {
+        m = parseManifest(repo, ref, file);
+      } catch (JAXBException | XMLStreamException e) {
+        throw new ConfigInvalidException("XML parse error", e);
+      }
       if (m.imports.getImports().length != 0) {
-        throw new Exception(
+        throw new ConfigInvalidException(
             String.format("Manifest %s contains remote imports which are not supported", file));
       }
 
@@ -53,7 +61,7 @@
         project.fillDefault();
         if (projectMap.containsKey(project.Key())) {
           if (!projectMap.get(project.Key()).equals(project))
-            throw new Exception(
+            throw new ConfigInvalidException(
                 String.format(
                     "Duplicate conflicting project %s in manifest %s\n%s\n%s",
                     project.Key(),
@@ -65,7 +73,12 @@
         }
       }
 
-      URI parentURI = new URI(file);
+      URI parentURI;
+      try {
+        parentURI = new URI(file);
+      } catch (URISyntaxException e) {
+        throw new ConfigInvalidException("Invalid parent URI", e);
+      }
       for (JiriManifest.LocalImport l : m.imports.getLocalImports()) {
         q.add(parentURI.resolve(l.getFile()).getPath());
       }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/supermanifest/JiriUpdater.java b/src/main/java/com/googlesource/gerrit/plugins/supermanifest/JiriUpdater.java
index 981e867..3e92349 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/supermanifest/JiriUpdater.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/supermanifest/JiriUpdater.java
@@ -3,13 +3,16 @@
 import static com.google.gerrit.reviewdb.client.RefNames.REFS_HEADS;
 
 import com.googlesource.gerrit.plugins.supermanifest.SuperManifestRefUpdatedListener.GerritRemoteReader;
+import java.io.IOException;
 import java.net.URI;
 import java.text.MessageFormat;
 import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
+import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.api.errors.JGitInternalException;
 import org.eclipse.jgit.dircache.DirCache;
 import org.eclipse.jgit.dircache.DirCacheBuilder;
 import org.eclipse.jgit.dircache.DirCacheEntry;
+import org.eclipse.jgit.errors.ConfigInvalidException;
 import org.eclipse.jgit.gitrepo.internal.RepoText;
 import org.eclipse.jgit.internal.JGitText;
 import org.eclipse.jgit.lib.CommitBuilder;
@@ -45,8 +48,7 @@
 
   private void updateSubmodules(
       Repository repo, String targetRef, JiriProjects projects, GerritRemoteReader reader)
-      throws Exception {
-
+      throws IOException, GitAPIException {
     DirCache index = DirCache.newInCore();
     DirCacheBuilder builder = index.builder();
     ObjectInserter inserter = repo.newObjectInserter();
@@ -154,7 +156,8 @@
   }
 
   @Override
-  public void update(GerritRemoteReader reader, ConfigEntry c, String srcRef) throws Exception {
+  public void update(GerritRemoteReader reader, ConfigEntry c, String srcRef)
+      throws IOException, GitAPIException, ConfigInvalidException {
     Repository srcRepo = reader.openRepository(c.getSrcRepoKey().toString());
     Repository destRepo = reader.openRepository(c.getDestRepoKey().toString());
     JiriProjects projects = JiriManifestParser.getProjects(srcRepo, srcRef, c.getXmlPath());
diff --git a/src/main/java/com/googlesource/gerrit/plugins/supermanifest/RepoUpdater.java b/src/main/java/com/googlesource/gerrit/plugins/supermanifest/RepoUpdater.java
index c385eee..d04506e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/supermanifest/RepoUpdater.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/supermanifest/RepoUpdater.java
@@ -21,6 +21,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.net.URI;
+import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.gitrepo.ManifestParser;
 import org.eclipse.jgit.gitrepo.RepoCommand;
 import org.eclipse.jgit.lib.PersonIdent;
@@ -34,7 +35,8 @@
   }
 
   @Override
-  public void update(GerritRemoteReader reader, ConfigEntry c, String srcRef) throws Exception {
+  public void update(GerritRemoteReader reader, ConfigEntry c, String srcRef) throws
+      IOException, GitAPIException {
     Repository destRepo = reader.openRepository(c.getDestRepoKey().toString());
     Repository srcRepo = reader.openRepository(c.getSrcRepoKey().toString());
 
diff --git a/src/main/java/com/googlesource/gerrit/plugins/supermanifest/SubModuleUpdater.java b/src/main/java/com/googlesource/gerrit/plugins/supermanifest/SubModuleUpdater.java
index 421beae..30f3d00 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/supermanifest/SubModuleUpdater.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/supermanifest/SubModuleUpdater.java
@@ -15,9 +15,13 @@
 package com.googlesource.gerrit.plugins.supermanifest;
 
 import com.googlesource.gerrit.plugins.supermanifest.SuperManifestRefUpdatedListener.GerritRemoteReader;
+import java.io.IOException;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.errors.ConfigInvalidException;
 
 interface SubModuleUpdater {
 
   /** Reads manifest and generates sub modules */
-  void update(GerritRemoteReader reader, ConfigEntry c, String srcRef) throws Exception;
+  void update(GerritRemoteReader reader, ConfigEntry c, String srcRef)
+      throws IOException, GitAPIException, ConfigInvalidException;
 }
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 ed153d6..ca339ac 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/supermanifest/SuperManifestRefUpdatedListener.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/supermanifest/SuperManifestRefUpdatedListener.java
@@ -232,24 +232,8 @@
       }
 
       try {
-        SubModuleUpdater subModuleUpdater;
-        switch (c.getToolType()) {
-          case Repo:
-            subModuleUpdater = new RepoUpdater(serverIdent, canonicalWebUrl);
-            break;
-          case Jiri:
-            subModuleUpdater = new JiriUpdater(serverIdent, canonicalWebUrl);
-            break;
-          default:
-            throw new ConfigInvalidException(
-                String.format("invalid toolType: %s", c.getToolType().name()));
-        }
-        try (GerritRemoteReader reader = new GerritRemoteReader()) {
-          subModuleUpdater.update(reader, c, event.getRefName());
-        }
-      } catch (
-          Exception
-              e) { //catch all exceptions as gerrit doesn't print stack trace for thrown Exception
+        updateForConfig(c, event);
+      } catch (ConfigInvalidException | 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];
@@ -267,6 +251,24 @@
     }
   }
 
+  private void updateForConfig(ConfigEntry c, Event event) throws ConfigInvalidException, IOException, GitAPIException {
+    SubModuleUpdater subModuleUpdater;
+    switch (c.getToolType()) {
+      case Repo:
+        subModuleUpdater = new RepoUpdater(serverIdent, canonicalWebUrl);
+        break;
+      case Jiri:
+        subModuleUpdater = new JiriUpdater(serverIdent, canonicalWebUrl);
+        break;
+      default:
+        throw new ConfigInvalidException(
+            String.format("invalid toolType: %s", c.getToolType().name()));
+    }
+    try (GerritRemoteReader reader = new GerritRemoteReader()) {
+      subModuleUpdater.update(reader, c, event.getRefName());
+    }
+  }
+
   /**
    * Remove boring stack frames. This retains the innermost frames up to and including the {@code
    * class#method} passed in {@code ref}.