Bug 458123 - don't mask Error or RuntimeException from getArtifact in
MirrorRequest

Change-Id: Iac5f2ae2666d539805f899f64dece3361b882675
Signed-off-by: Christian Schneider <schneider@yatta.de>
diff --git a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorRequest.java b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorRequest.java
index 5594162..a08b396 100644
--- a/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorRequest.java
+++ b/bundles/org.eclipse.equinox.p2.artifact.repository/src/org/eclipse/equinox/internal/p2/artifact/repository/MirrorRequest.java
@@ -207,6 +207,11 @@
 		do {
 			lastResult = transferSingle(destinationDescriptor, sourceDescriptor, monitor);
 			allResults.add(lastResult);
+			if (lastResult.getException() instanceof Error)
+			{
+				// Error is more severe than Exception - e.g. an OutOfMemoryError should not be ignored and might hinder further processing
+				throw (Error) lastResult.getException();
+			}
 		} while (lastResult.getSeverity() == IStatus.ERROR && lastResult.getCode() == IArtifactRepository.CODE_RETRY && counter++ < MAX_RETRY_REQUEST);
 		IProvisioningEventBus bus = (IProvisioningEventBus) source.getProvisioningAgent().getService(IProvisioningEventBus.SERVICE_NAME);
 		if (bus != null)
@@ -262,6 +267,7 @@
 		}
 
 		IStatus status = null;
+		Throwable priorException = null;
 		// Do the actual transfer
 		try {
 			status = getArtifact(sourceDescriptor, destination, monitor);
@@ -271,13 +277,24 @@
 				Throwable e = root != null ? root.getException() : null;
 				((IStateful) destination).setStatus(new MultiStatus(Activator.ID, status.getCode(), new IStatus[] {status, destStatus}, status.getMessage(), e));
 			}
+		} catch (RuntimeException e)
+		{
+			priorException = e;
+			throw e;
+		} catch (Error e) {
+			priorException = e;
+			throw e;
 		} finally {
 			try {
 				destination.close();
 			} catch (IOException e) {
-				if (status != null && status.getSeverity() == IStatus.ERROR && status.getCode() == IArtifactRepository.CODE_RETRY)
-					return new MultiStatus(Activator.ID, status.getCode(), new IStatus[] {status}, NLS.bind(Messages.error_closing_stream, getArtifactKey(), target.getLocation()), e);
-				return new Status(IStatus.ERROR, Activator.ID, NLS.bind(Messages.error_closing_stream, getArtifactKey(), target.getLocation()), e);
+				if (priorException == null) // don't mask a formerly thrown Exception/Error
+				{
+					if (status != null && status.getSeverity() == IStatus.ERROR && status.getCode() == IArtifactRepository.CODE_RETRY)
+						return new MultiStatus(Activator.ID, status.getCode(), new IStatus[] {status}, NLS.bind(Messages.error_closing_stream, getArtifactKey(), target.getLocation()), e);
+					return new Status(IStatus.ERROR, Activator.ID, NLS.bind(Messages.error_closing_stream, getArtifactKey(), target.getLocation()), e);
+				}
+				// otherwise it is already thrown
 			}
 		}
 		return status;