LUCENE-1214: preseve original exception in SegmentInfos write & commit

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@636467 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael McCandless 2008-03-12 19:23:17 +00:00
parent e5f9b4e1cb
commit 4b3709be87
3 changed files with 87 additions and 9 deletions

View File

@ -300,13 +300,29 @@ final class SegmentInfos extends Vector {
} finally {
boolean success2 = false;
try {
output.close();
success2 = true;
if (!success) {
// We hit an exception above; try to close the file
// but suppress any exception:
try {
output.close();
success2 = true;
} catch (Throwable t) {
// Suppress so we keep throwing the original exception
}
} else {
output.close();
success2 = true;
}
} finally {
if (!success || !success2)
// Try not to leave a truncated segments_N file in
// the index:
directory.deleteFile(segmentFileName);
if (!success || !success2) {
try {
// Try not to leave a truncated segments_N file in
// the index:
directory.deleteFile(segmentFileName);
} catch (Throwable t) {
// Suppress so we keep throwing the original exception
}
}
}
}
@ -738,7 +754,11 @@ final class SegmentInfos extends Vector {
final String segmentFileName = IndexFileNames.fileNameFromGeneration(IndexFileNames.SEGMENTS,
"",
generation);
dir.deleteFile(segmentFileName);
try {
dir.deleteFile(segmentFileName);
} catch (Throwable t) {
// Suppress so we keep throwing the original exception
}
}
}
@ -758,8 +778,13 @@ final class SegmentInfos extends Vector {
dir.sync(fileName);
success = true;
} finally {
if (!success)
dir.deleteFile(fileName);
if (!success) {
try {
dir.deleteFile(fileName);
} catch (Throwable t) {
// Suppress so we keep throwing the original exception
}
}
}
}
}

View File

@ -3268,4 +3268,54 @@ public class TestIndexWriter extends LuceneTestCase
dir.close();
}
private static class FailOnlyInCommit extends MockRAMDirectory.Failure {
boolean fail1, fail2;
public void eval(MockRAMDirectory dir) throws IOException {
StackTraceElement[] trace = new Exception().getStackTrace();
boolean isCommit = false;
boolean isDelete = false;
for (int i = 0; i < trace.length; i++) {
if ("org.apache.lucene.index.SegmentInfos".equals(trace[i].getClassName()) && "commit".equals(trace[i].getMethodName()))
isCommit = true;
if ("org.apache.lucene.store.MockRAMDirectory".equals(trace[i].getClassName()) && "deleteFile".equals(trace[i].getMethodName()))
isDelete = true;
}
if (isCommit) {
if (!isDelete) {
fail1 = true;
throw new RuntimeException("now fail first");
} else {
fail2 = true;
throw new IOException("now fail during delete");
}
}
}
}
// LUCENE-1214
public void testExceptionsDuringCommit() throws Throwable {
MockRAMDirectory dir = new MockRAMDirectory();
FailOnlyInCommit failure = new FailOnlyInCommit();
IndexWriter w = new IndexWriter(dir, false, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.UNLIMITED);
Document doc = new Document();
doc.add(new Field("field", "a field", Field.Store.YES,
Field.Index.TOKENIZED));
w.addDocument(doc);
dir.failOn(failure);
try {
w.close();
fail();
} catch (IOException ioe) {
fail("expected only RuntimeException");
} catch (RuntimeException re) {
// Expected
}
assertTrue(failure.fail1 && failure.fail2);
w.abort();
dir.close();
}
}

View File

@ -186,6 +186,9 @@ public class MockRAMDirectory extends RAMDirectory {
}
private synchronized void deleteFile(String name, boolean forced) throws IOException {
maybeThrowDeterministicException();
if (crashed && !forced)
throw new IOException("cannot delete after crash");