diff options
author | Shawn O. Pearce <spearce@spearce.org> | 2010-08-30 11:53:25 -0700 |
---|---|---|
committer | Shawn O. Pearce <spearce@spearce.org> | 2010-08-30 11:53:25 -0700 |
commit | e6bd689d2c48efb4e6662ffca2fbdbc7570d2db1 (patch) | |
tree | 0b19b3c1a845a0626c61ba1c7954cfd2f8844834 /org.eclipse.jgit/src/org/eclipse | |
parent | a3945d1bc856322becdc4d1ec8df9013bfef3175 (diff) | |
download | jgit-e6bd689d2c48efb4e6662ffca2fbdbc7570d2db1.tar.gz jgit-e6bd689d2c48efb4e6662ffca2fbdbc7570d2db1.zip |
Improve LargeObjectException reporting
Use 3 different types of LargeObjectException for the 3 major ways
that we can fail to load an object. For each of these use a unique
string translation which describes the root cause better than just
the ObjectId.name() does.
Change-Id: I810c98d5691b74af9fc6cbd46fc9879e35a7bdca
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse')
7 files changed, 106 insertions, 13 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java index fc12e57135..ea40fe8847 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java @@ -276,6 +276,10 @@ public class JGitText extends TranslationBundle { /***/ public String invalidWindowSize; /***/ public String isAStaticFlagAndHasNorevWalkInstance; /***/ public String kNotInRange; + /***/ public String largeObjectException; + /***/ public String largeObjectOutOfMemory; + /***/ public String largeObjectExceedsByteArray; + /***/ public String largeObjectExceedsLimit; /***/ public String lengthExceedsMaximumArraySize; /***/ public String listingAlternates; /***/ public String localObjectsIncomplete; @@ -433,6 +437,7 @@ public class JGitText extends TranslationBundle { /***/ public String unknownDIRCVersion; /***/ public String unknownHost; /***/ public String unknownIndexVersionOrCorruptIndex; + /***/ public String unknownObject; /***/ public String unknownObjectType; /***/ public String unknownRepositoryFormat2; /***/ public String unknownRepositoryFormat; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/LargeObjectException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/LargeObjectException.java index f77aecbb42..a1107dc35f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/errors/LargeObjectException.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/errors/LargeObjectException.java @@ -43,6 +43,9 @@ package org.eclipse.jgit.errors; +import java.text.MessageFormat; + +import org.eclipse.jgit.JGitText; import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.ObjectId; @@ -73,6 +76,13 @@ public class LargeObjectException extends RuntimeException { return objectId; } + /** @return either the hex encoded name of the object, or 'unknown object'. */ + protected String getObjectName() { + if (getObjectId() != null) + return getObjectId().name(); + return JGitText.get().unknownObject; + } + /** * Set the identity of the object, if its not already set. * @@ -86,6 +96,68 @@ public class LargeObjectException extends RuntimeException { @Override public String getMessage() { - return objectId != null ? objectId.name() : getClass().getSimpleName(); + return MessageFormat.format(JGitText.get().largeObjectException, + getObjectName()); + } + + /** An error caused by the JVM being out of heap space. */ + public static class OutOfMemory extends LargeObjectException { + private static final long serialVersionUID = 1L; + + /** + * Construct a wrapper around the original OutOfMemoryError. + * + * @param cause + * the original root cause. + */ + public OutOfMemory(OutOfMemoryError cause) { + initCause(cause); + } + + @Override + public String getMessage() { + return MessageFormat.format(JGitText.get().largeObjectOutOfMemory, + getObjectName()); + } + } + + /** Object size exceeds JVM limit of 2 GiB per byte array. */ + public static class ExceedsByteArrayLimit extends LargeObjectException { + private static final long serialVersionUID = 1L; + + @Override + public String getMessage() { + return MessageFormat + .format(JGitText.get().largeObjectExceedsByteArray, + getObjectName()); + } + } + + /** Object size exceeds the caller's upper limit. */ + public static class ExceedsLimit extends LargeObjectException { + private static final long serialVersionUID = 1L; + + private final long limit; + + private final long size; + + /** + * Construct an exception for a particular size being exceeded. + * + * @param limit + * the limit the caller imposed on the object. + * @param size + * the actual size of the object. + */ + public ExceedsLimit(long limit, long size) { + this.limit = limit; + this.size = size; + } + + @Override + public String getMessage() { + return MessageFormat.format(JGitText.get().largeObjectExceedsLimit, + getObjectName(), limit, size); + } } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectLoader.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectLoader.java index b7e58ea156..0fc3bce65b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectLoader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectLoader.java @@ -139,7 +139,7 @@ public abstract class ObjectLoader { try { return cloneArray(cached); } catch (OutOfMemoryError tooBig) { - throw new LargeObjectException(); + throw new LargeObjectException.OutOfMemory(tooBig); } } @@ -195,14 +195,17 @@ public abstract class ObjectLoader { ObjectStream in = openStream(); try { long sz = in.getSize(); - if (sizeLimit < sz || Integer.MAX_VALUE < sz) - throw new LargeObjectException(); + if (sizeLimit < sz) + throw new LargeObjectException.ExceedsLimit(sizeLimit, sz); + + if (Integer.MAX_VALUE < sz) + throw new LargeObjectException.ExceedsByteArrayLimit(); byte[] buf; try { buf = new byte[(int) sz]; } catch (OutOfMemoryError notEnoughHeap) { - throw new LargeObjectException(); + throw new LargeObjectException.OutOfMemory(notEnoughHeap); } IO.readFully(in, buf, 0, buf.length); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/LargePackedDeltaObject.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/LargePackedDeltaObject.java index 02e218216d..2b98f107f8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/LargePackedDeltaObject.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/LargePackedDeltaObject.java @@ -157,7 +157,9 @@ class LargePackedDeltaObject extends ObjectLoader { try { throw new LargeObjectException(getObjectId()); } catch (IOException cannotObtainId) { - throw new LargeObjectException(); + LargeObjectException err = new LargeObjectException(); + err.initCause(cannotObtainId); + throw err; } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/LargePackedWholeObject.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/LargePackedWholeObject.java index 9f5b804ce4..9550be4e1d 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/LargePackedWholeObject.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/LargePackedWholeObject.java @@ -97,7 +97,9 @@ class LargePackedWholeObject extends ObjectLoader { try { throw new LargeObjectException(getObjectId()); } catch (IOException cannotObtainId) { - throw new LargeObjectException(); + LargeObjectException err = new LargeObjectException(); + err.initCause(cannotObtainId); + throw err; } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/UnpackedObject.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/UnpackedObject.java index 78e7b10a7d..4065019dc5 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/UnpackedObject.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/UnpackedObject.java @@ -125,8 +125,12 @@ public class UnpackedObject { if (hdr[p.value++] != 0) throw new CorruptObjectException(id, JGitText.get().corruptObjectGarbageAfterSize); - if (path == null && Integer.MAX_VALUE < size) - throw new LargeObjectException(id.copy()); + if (path == null && Integer.MAX_VALUE < size) { + LargeObjectException.ExceedsByteArrayLimit e; + e = new LargeObjectException.ExceedsByteArrayLimit(); + e.setObjectId(id); + throw e; + } if (size < wc.getStreamFileThreshold() || path == null) { byte[] data = new byte[(int) size]; int n = avail - p.value; @@ -163,8 +167,12 @@ public class UnpackedObject { JGitText.get().corruptObjectInvalidType); } - if (path == null && Integer.MAX_VALUE < size) - throw new LargeObjectException(id.copy()); + if (path == null && Integer.MAX_VALUE < size) { + LargeObjectException.ExceedsByteArrayLimit e; + e = new LargeObjectException.ExceedsByteArrayLimit(); + e.setObjectId(id); + throw e; + } if (size < wc.getStreamFileThreshold() || path == null) { in.reset(); IO.skipFully(in, p); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/DeltaWindow.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/DeltaWindow.java index d5296a03e3..6a71ad7dcf 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/DeltaWindow.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/DeltaWindow.java @@ -424,8 +424,9 @@ class DeltaWindow { try { idx = new DeltaIndex(buffer(ent)); } catch (OutOfMemoryError noMemory) { - LargeObjectException e = new LargeObjectException(ent.object); - e.initCause(noMemory); + LargeObjectException.OutOfMemory e; + e = new LargeObjectException.OutOfMemory(noMemory); + e.setObjectId(ent.object); throw e; } if (0 < maxMemory) |