]> source.dussan.org Git - jgit.git/commitdiff
ReceivePack: Rethrow exceptions caught during indexing 24/1524/1
authorShawn O. Pearce <spearce@spearce.org>
Fri, 3 Sep 2010 16:38:30 +0000 (09:38 -0700)
committerShawn O. Pearce <spearce@spearce.org>
Fri, 3 Sep 2010 17:57:55 +0000 (10:57 -0700)
If we get an exception while indexing the incoming pack, its likely
a stream corruption.  We already report an error to the client, but
we eat the stack trace, which makes debugging issues related to a
bug inside of JGit nearly impossible.  Rethrow it under a new type
UnpackException, so embedding servers or applications can catch the
error and provide it to a human who might be able to forward such
traces onto a JGit developer for evaluation.

Change-Id: Icad41148bbc0c76f284c7033a195a6b51911beab
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/ReceivePackRefFilterTest.java
org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties
org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java
org.eclipse.jgit/src/org/eclipse/jgit/errors/UnpackException.java [new file with mode: 0644]
org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java

index f89959c68c2f4c83e4ed99256893d750aae3c1e7..edced2fbb791f0ff7c9586d8b1848c1df97633ac 100644 (file)
@@ -52,6 +52,8 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.zip.Deflater;
 
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.errors.UnpackException;
 import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
 import org.eclipse.jgit.junit.TestRepository;
 import org.eclipse.jgit.lib.Constants;
@@ -240,7 +242,15 @@ public class ReceivePackRefFilterTest extends LocalDiskRepositoryTestCase {
                rp.setCheckReceivedObjects(true);
                rp.setCheckReferencedObjectsAreReachable(true);
                rp.setRefFilter(new HidePrivateFilter());
-               rp.receive(new ByteArrayInputStream(inBuf.toByteArray()), outBuf, null);
+               try {
+                       receive(rp, inBuf, outBuf);
+                       fail("Expected UnpackException");
+               } catch (UnpackException failed) {
+                       Throwable err = failed.getCause();
+                       assertTrue(err instanceof MissingObjectException);
+                       MissingObjectException moe = (MissingObjectException) err;
+                       assertEquals(P, moe.getObjectId());
+               }
 
                final PacketLineIn r = asPacketLineIn(outBuf);
                String master = r.readString();
@@ -254,6 +264,12 @@ public class ReceivePackRefFilterTest extends LocalDiskRepositoryTestCase {
                assertSame(PacketLineIn.END, r.readString());
        }
 
+       private void receive(final ReceivePack rp,
+                       final TemporaryBuffer.Heap inBuf, final TemporaryBuffer.Heap outBuf)
+                       throws IOException {
+               rp.receive(new ByteArrayInputStream(inBuf.toByteArray()), outBuf, null);
+       }
+
        public void testUsingHiddenDeltaBaseFails() throws Exception {
                final TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024);
                packHeader(pack, 1);
@@ -275,7 +291,15 @@ public class ReceivePackRefFilterTest extends LocalDiskRepositoryTestCase {
                rp.setCheckReceivedObjects(true);
                rp.setCheckReferencedObjectsAreReachable(true);
                rp.setRefFilter(new HidePrivateFilter());
-               rp.receive(new ByteArrayInputStream(inBuf.toByteArray()), outBuf, null);
+               try {
+                       receive(rp, inBuf, outBuf);
+                       fail("Expected UnpackException");
+               } catch (UnpackException failed) {
+                       Throwable err = failed.getCause();
+                       assertTrue(err instanceof MissingObjectException);
+                       MissingObjectException moe = (MissingObjectException) err;
+                       assertEquals(b, moe.getObjectId());
+               }
 
                final PacketLineIn r = asPacketLineIn(outBuf);
                String master = r.readString();
@@ -316,7 +340,15 @@ public class ReceivePackRefFilterTest extends LocalDiskRepositoryTestCase {
                rp.setCheckReceivedObjects(true);
                rp.setCheckReferencedObjectsAreReachable(true);
                rp.setRefFilter(new HidePrivateFilter());
-               rp.receive(new ByteArrayInputStream(inBuf.toByteArray()), outBuf, null);
+               try {
+                       receive(rp, inBuf, outBuf);
+                       fail("Expected UnpackException");
+               } catch (UnpackException failed) {
+                       Throwable err = failed.getCause();
+                       assertTrue(err instanceof MissingObjectException);
+                       MissingObjectException moe = (MissingObjectException) err;
+                       assertEquals(b, moe.getObjectId());
+               }
 
                final PacketLineIn r = asPacketLineIn(outBuf);
                String master = r.readString();
@@ -358,7 +390,15 @@ public class ReceivePackRefFilterTest extends LocalDiskRepositoryTestCase {
                rp.setCheckReceivedObjects(true);
                rp.setCheckReferencedObjectsAreReachable(true);
                rp.setRefFilter(new HidePrivateFilter());
-               rp.receive(new ByteArrayInputStream(inBuf.toByteArray()), outBuf, null);
+               try {
+                       receive(rp, inBuf, outBuf);
+                       fail("Expected UnpackException");
+               } catch (UnpackException failed) {
+                       Throwable err = failed.getCause();
+                       assertTrue(err instanceof MissingObjectException);
+                       MissingObjectException moe = (MissingObjectException) err;
+                       assertEquals(n, moe.getObjectId());
+               }
 
                final PacketLineIn r = asPacketLineIn(outBuf);
                String master = r.readString();
@@ -397,7 +437,15 @@ public class ReceivePackRefFilterTest extends LocalDiskRepositoryTestCase {
                rp.setCheckReceivedObjects(true);
                rp.setCheckReferencedObjectsAreReachable(true);
                rp.setRefFilter(new HidePrivateFilter());
-               rp.receive(new ByteArrayInputStream(inBuf.toByteArray()), outBuf, null);
+               try {
+                       receive(rp, inBuf, outBuf);
+                       fail("Expected UnpackException");
+               } catch (UnpackException failed) {
+                       Throwable err = failed.getCause();
+                       assertTrue(err instanceof MissingObjectException);
+                       MissingObjectException moe = (MissingObjectException) err;
+                       assertEquals(t, moe.getObjectId());
+               }
 
                final PacketLineIn r = asPacketLineIn(outBuf);
                String master = r.readString();
index 14c0ba0fc8c25bc917198a54b1ae2cc1f35f9501..017fc5da989e415227a2ebd79a20c76551a4e9ca 100644 (file)
@@ -383,6 +383,7 @@ unknownObjectType=Unknown object type {0}.
 unknownRepositoryFormat2=Unknown repository format "{0}"; expected "0".
 unknownRepositoryFormat=Unknown repository format
 unknownZlibError=Unknown zlib error.
+unpackException=Exception while parsing pack stream
 unmergedPath=Unmerged path: {0}
 unreadablePackIndex=Unreadable pack index: {0}
 unrecognizedRef=Unrecognized ref: {0}
index ea40fe8847405ac80f092499aaaa10df41bc8625..055864ccc1e86d9b30c67dc22dffa619836627c1 100644 (file)
@@ -443,6 +443,7 @@ public class JGitText extends TranslationBundle {
        /***/ public String unknownRepositoryFormat;
        /***/ public String unknownZlibError;
        /***/ public String unmergedPath;
+       /***/ public String unpackException;
        /***/ public String unreadablePackIndex;
        /***/ public String unrecognizedRef;
        /***/ public String unsupportedCommand0;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/errors/UnpackException.java b/org.eclipse.jgit/src/org/eclipse/jgit/errors/UnpackException.java
new file mode 100644 (file)
index 0000000..cf95521
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2010, Google Inc.
+ * and other copyright owners as documented in the project's IP log.
+ *
+ * This program and the accompanying materials are made available
+ * under the terms of the Eclipse Distribution License v1.0 which
+ * accompanies this distribution, is reproduced below, and is
+ * available at http://www.eclipse.org/org/documents/edl-v10.php
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or
+ * without modification, are permitted provided that the following
+ * conditions are met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials provided
+ *   with the distribution.
+ *
+ * - Neither the name of the Eclipse Foundation, Inc. nor the
+ *   names of its contributors may be used to endorse or promote
+ *   products derived from this software without specific prior
+ *   written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package org.eclipse.jgit.errors;
+
+import java.io.IOException;
+
+import org.eclipse.jgit.JGitText;
+
+/** Indicates a ReceivePack failure while scanning the pack stream. */
+public class UnpackException extends IOException {
+       private static final long serialVersionUID = 1L;
+
+       /**
+        * Creates an exception with a root cause.
+        *
+        * @param why
+        *            the root cause of the unpacking failure.
+        */
+       public UnpackException(Throwable why) {
+               super(JGitText.get().unpackException);
+               initCause(why);
+       }
+}
index f77e8e6ee4ca2f8b31645a42d60ec56286edd7cf..53a3841173e4ef4ca93deaaf71aa12ce7cde0cc3 100644 (file)
@@ -68,6 +68,7 @@ import java.util.Set;
 import org.eclipse.jgit.JGitText;
 import org.eclipse.jgit.errors.MissingObjectException;
 import org.eclipse.jgit.errors.PackProtocolException;
+import org.eclipse.jgit.errors.UnpackException;
 import org.eclipse.jgit.lib.Config;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.NullProgressMonitor;
@@ -661,6 +662,9 @@ public class ReceivePack {
                        }
 
                        postReceive.onPostReceive(this, filterCommands(Result.OK));
+
+                       if (unpackError != null)
+                               throw new UnpackException(unpackError);
                }
        }