> A common superclass for JGit exceptions sounds harmless to me if JGit never uses it. :)
Note that I want this common exception specifically for JGit's low-level parts. I think JGit client code (org.eclipse.jgit.api.*) and JGit server code (ReceivePack and UploadPack) might just want to catch with this root exception class since they are anyway not interested in what kind of JGitException it is in many cases.
> The main other API I like to look at as an example, Guava, doesn't have a common base class for its exceptions. Is there a reason callers that don't care about the particular exception type would need such a thing instead of using Exception?
When an interface is defined (the word "interface" here is a generic term to refer an abstraction), there should be a case where "as a user, I don't care which implementation it is, but I just want one". I think this root exception is also such interface. The question to be asked should be "is there a case where a caller wants to catch only exceptions thrown by JGit, but doesn't care if it's a CorruptPackIndexException or a DirCacheNameConflictException?". I think there is a case. To answer your question more directly, yes. A caller might not be interested in whether an exception thrown by JGit is a particular exception, but it doesn't mean they are not interested in any Exception type. For example, imagine that there is a server that wants to return a blob content for some request. There would be code like:
try (Repository repo = openRepository(...)) {
ObjectReader or = repo.getObjectReader();
if (!or.hasObjectId(requestedObjectId)) {
throw new BadRequestException("%s doesn't exist in the repository", requestedObjectId);
}
return or.open(requestedObjectId).getBytes();
} catch (JGitException e) {
throw new BackendRuntimeException(e);
}
If there's no JGitException and the server needs to catch IndexReadException, CorruptPackIndexException, MissingObjectException, TooLargeObjectInPackException, UnsupportedPackVersionException, UnsupportedPackIndexVersionException, PackInvalidException, PackMismatchException, etc.. (I'm guessing this list from the names, but I don't think I'm that wrong.) I think forcing callers to list all of them in the catch clause would be impractical.
If this code is rewritten to catch Exception:
try (Repository repo = openRepository(...)) {
ObjectReader or = repo.getObjectReader();
if (!or.hasObjectId(requestedObjectId)) {
throw new BadRequestException("%s doesn't exist in the repository", requestedObjectId);
}
return or.open(requestedObjectId).getBytes();
} catch (BadRequestException e) {
// We need to re-catch this so that this is not converted to BackendRuntimeException.
throw e;
} catch (Exception e) {
// Doubtful...
throw new BackendRuntimeException(e);
}
Because catch Exception will catch RuntimeExceptions, it needs to catch it inside the code to avoid wrapped to another exception. Having catch Exception makes a code smell. If this try-with-resources block starts using some library that is not from JGit (like making an RPC?) those exceptions are caught by this Exception catch, which was really meant for JGit exceptions only.
Guava, and I think Apache commons also, are a collection of common utility classes. I guess even if Guava defines a root exception, there's no case that a caller want to catch any exception from Guava. There's no relationship in, say, ImmutableList and InetAddress, then there's no case a caller wants to catch a common "GuavaException".
That said, I tried to find if there's an example, but I couldn't find a library that defines many checked exceptions. Java standard library defines a lot of checked exceptions, but I'm not sure if it's a good example... This is a Javadoc page that I host
https://docs.java-plus-you-download.today/javadoc/overview-tree.html, and it contains multiple OSS libraries. Looking at the Exception tree, I can see exceptions like GeneralSecurityException, SocketException, etc. that have a hierarchy, but not from the 3rd party ones. Also I cannot find an example that have a flat structure (i.e. all exceptions inherit directly from Exception).