From 4b3709be872cd6e556be7e20125b849d6135f1f5 Mon Sep 17 00:00:00 2001 From: Michael McCandless Date: Wed, 12 Mar 2008 19:23:17 +0000 Subject: [PATCH] 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 --- .../org/apache/lucene/index/SegmentInfos.java | 43 ++++++++++++---- .../apache/lucene/index/TestIndexWriter.java | 50 +++++++++++++++++++ .../apache/lucene/store/MockRAMDirectory.java | 3 ++ 3 files changed, 87 insertions(+), 9 deletions(-) diff --git a/src/java/org/apache/lucene/index/SegmentInfos.java b/src/java/org/apache/lucene/index/SegmentInfos.java index 21f12326c03..f0e8acfa6c7 100644 --- a/src/java/org/apache/lucene/index/SegmentInfos.java +++ b/src/java/org/apache/lucene/index/SegmentInfos.java @@ -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 + } + } } } } diff --git a/src/test/org/apache/lucene/index/TestIndexWriter.java b/src/test/org/apache/lucene/index/TestIndexWriter.java index bd653389b82..a4f312a2919 100644 --- a/src/test/org/apache/lucene/index/TestIndexWriter.java +++ b/src/test/org/apache/lucene/index/TestIndexWriter.java @@ -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(); + } } diff --git a/src/test/org/apache/lucene/store/MockRAMDirectory.java b/src/test/org/apache/lucene/store/MockRAMDirectory.java index 0763b779633..176773ebacc 100644 --- a/src/test/org/apache/lucene/store/MockRAMDirectory.java +++ b/src/test/org/apache/lucene/store/MockRAMDirectory.java @@ -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");