diff src/org/tmatesoft/hg/internal/RevlogStream.java @ 366:189dc6dc1c3e

Use exceptions to expose errors reading mercurial data
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Fri, 16 Dec 2011 04:43:18 +0100
parents 5f9073eabf06
children 2fadf8695f8a
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/internal/RevlogStream.java	Sun Dec 11 00:39:07 2011 +0100
+++ b/src/org/tmatesoft/hg/internal/RevlogStream.java	Fri Dec 16 04:43:18 2011 +0100
@@ -24,6 +24,7 @@
 import java.util.zip.Inflater;
 
 import org.tmatesoft.hg.core.HgBadStateException;
+import org.tmatesoft.hg.core.HgException;
 import org.tmatesoft.hg.core.HgInvalidControlFileException;
 import org.tmatesoft.hg.core.HgInvalidRevisionException;
 import org.tmatesoft.hg.core.Nodeid;
@@ -181,7 +182,7 @@
 
 	// should be possible to use TIP, ALL, or -1, -2, -n notation of Hg
 	// ? boolean needsNodeid
-	public void iterate(int start, int end, boolean needData, Inspector inspector) throws HgInvalidRevisionException {
+	public void iterate(int start, int end, boolean needData, Inspector inspector) throws HgInvalidRevisionException, HgInvalidControlFileException /*REVISIT - too general exception*/ {
 		initOutline();
 		final int indexSize = revisionCount();
 		if (indexSize == 0) {
@@ -201,7 +202,11 @@
 			r.start(end - start + 1);
 			r.range(start, end);
 		} catch (IOException ex) {
-			throw new HgBadStateException(ex); // FIXME need better handling
+			throw new HgInvalidControlFileException(String.format("Failed reading [%d..%d]", start, end), ex, indexFile);
+		} catch (HgInvalidControlFileException ex) {
+			throw ex;
+		} catch (HgException ex) {
+			throw new HgInvalidControlFileException(String.format("Failed reading [%d..%d]", start, end), ex, indexFile);
 		} finally {
 			r.finish();
 		}
@@ -214,7 +219,7 @@
 	 * @param needData whether inspector needs access to header only
 	 * @param inspector callback to process entries
 	 */
-	public void iterate(int[] sortedRevisions, boolean needData, Inspector inspector) throws HgInvalidRevisionException {
+	public void iterate(int[] sortedRevisions, boolean needData, Inspector inspector) throws HgInvalidRevisionException, HgInvalidControlFileException /*REVISIT - too general exception*/ {
 		final int indexSize = revisionCount();
 		if (indexSize == 0 || sortedRevisions.length == 0) {
 			return;
@@ -245,7 +250,13 @@
 				}
 			}
 		} catch (IOException ex) {
-			throw new HgBadStateException(ex); // FIXME need better handling
+			final int c = sortedRevisions.length;
+			throw new HgInvalidControlFileException(String.format("Failed reading %d revisions in [%d; %d]",c, sortedRevisions[0], sortedRevisions[c-1]), ex, indexFile);
+		} catch (HgInvalidControlFileException ex) {
+			throw ex;
+		} catch (HgException ex) {
+			final int c = sortedRevisions.length;
+			throw new HgInvalidControlFileException(String.format("Failed reading %d revisions in [%d; %d]",c, sortedRevisions[0], sortedRevisions[c-1]), ex, indexFile);
 		} finally {
 			r.finish();
 		}
@@ -337,7 +348,7 @@
 				}
 			}
 		} catch (IOException ex) {
-			ex.printStackTrace(); // log error
+			ex.printStackTrace(); // FIXME, log error is not enough
 			// too bad, no outline then, but don't fail with NPE
 			baseRevisions = new int[0];
 		} finally {
@@ -347,7 +358,7 @@
 	
 	/**
 	 * operation with single file open/close and multiple diverse reads.
-	 * XXX initOutline might need similar extraction to keen N1 format knowledge  
+	 * XXX initOutline might need similar extraction to keep N1 format knowledge  
 	 */
 	class ReaderN1 {
 		private final Inspector inspector;
@@ -393,7 +404,7 @@
 //			System.out.printf("applyTime:%d ms, inspectorTime: %d ms\n", applyTime, inspectorTime); // TIMING
 		}
 
-		public boolean range(int start, int end) throws IOException {
+		public boolean range(int start, int end) throws IOException, HgException {
 			byte[] nodeidBuf = new byte[20];
 			int i;
 			// it (i.e. replace with i >= start)
@@ -517,6 +528,6 @@
 		// XXX boolean retVal to indicate whether to continue?
 		// TODO specify nodeid and data length, and reuse policy (i.e. if revlog stream doesn't reuse nodeid[] for each call)
 		// implementers shall not invoke DataAccess.done(), it's accomplished by #iterate at appropraite moment
-		void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[/*20*/] nodeid, DataAccess data);
+		void next(int revisionNumber, int actualLen, int baseRevision, int linkRevision, int parent1Revision, int parent2Revision, byte[/*20*/] nodeid, DataAccess data) throws HgException;
 	}
 }