Skip to content

Commit a5d5f6c

Browse files
committed
Do not throw RuntimeException from IFile.getContents(false) #2290
1 parent 0edd6a1 commit a5d5f6c

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/localstore/FileSystemResourceManager.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,10 @@ private IFileStore getFileStore(IFile target, boolean force) throws ResourceExce
935935
final IFileInfo fileInfo = store.fetchInfo();
936936
Resource resource = (Resource) target;
937937
ResourceInfo info = resource.getResourceInfo(true, false);
938+
if (info == null) {
939+
String message = NLS.bind(Messages.resources_mustExist, target.getFullPath());
940+
throw new ResourceException(IResourceStatus.RESOURCE_NOT_FOUND, target.getFullPath(), message, null);
941+
}
938942
if (fileInfo.getLastModified() != info.getLocalSyncInfo()) {
939943
asyncRefresh(target);
940944
String message = NLS.bind(Messages.localstore_resourceIsOutOfSync, target.getFullPath());

resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/resources/regression/IFileTest.java

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
*******************************************************************************/
1414
package org.eclipse.core.tests.resources.regression;
1515

16+
import static java.lang.System.currentTimeMillis;
1617
import static org.assertj.core.api.Assertions.assertThat;
1718
import static org.eclipse.core.resources.ResourcesPlugin.getWorkspace;
1819
import static org.eclipse.core.tests.resources.ResourceTestUtil.createInWorkspace;
@@ -24,14 +25,20 @@
2425
import static org.junit.jupiter.api.Assertions.assertEquals;
2526
import static org.junit.jupiter.api.Assertions.assertThrows;
2627

28+
import java.io.IOException;
29+
import java.io.InputStream;
30+
import java.io.OutputStream;
2731
import org.eclipse.core.resources.IFile;
2832
import org.eclipse.core.resources.IFolder;
2933
import org.eclipse.core.resources.IProject;
3034
import org.eclipse.core.resources.IProjectDescription;
3135
import org.eclipse.core.resources.IResource;
3236
import org.eclipse.core.resources.IResourceStatus;
3337
import org.eclipse.core.runtime.CoreException;
38+
import org.eclipse.core.runtime.IStatus;
3439
import org.eclipse.core.runtime.Platform.OS;
40+
import org.eclipse.core.runtime.Status;
41+
import org.eclipse.core.runtime.jobs.Job;
3542
import org.eclipse.core.tests.resources.util.WorkspaceResetExtension;
3643
import org.junit.jupiter.api.Disabled;
3744
import org.junit.jupiter.api.Test;
@@ -125,4 +132,82 @@ public void testBug43936() throws CoreException {
125132
project.setDescription(desc, createTestMonitor());
126133
}
127134

135+
/**
136+
* Do not throw RuntimeException when accessing a deleted file
137+
*/
138+
@Test
139+
public void testIssue2290() throws CoreException, InterruptedException {
140+
IProject project = getWorkspace().getRoot().getProject("MyProject");
141+
IFile subject = project.getFile("subject.txt");
142+
Job noise = Job.create("Create/delete", monitor -> {
143+
try {
144+
while (!monitor.isCanceled()) {
145+
createInWorkspace(subject);
146+
while (!monitor.isCanceled()) {
147+
try {
148+
subject.delete(true, monitor);
149+
break;
150+
} catch (CoreException e) {
151+
// On Windows, files opened for reading can't be deleted, try again
152+
if (e.getStatus().getCode() != IResourceStatus.FAILED_DELETE_LOCAL) {
153+
throw e;
154+
}
155+
}
156+
}
157+
}
158+
} catch (CoreException e) {
159+
return e.getStatus();
160+
}
161+
return Status.OK_STATUS;
162+
});
163+
noise.setPriority(Job.INTERACTIVE);
164+
165+
long stop = currentTimeMillis() + 1000;
166+
try {
167+
noise.schedule();
168+
while (currentTimeMillis() < stop) {
169+
assertContentAccessibleOrNotFound(subject); // should not throw
170+
}
171+
} finally {
172+
noise.cancel();
173+
noise.join();
174+
IStatus result = noise.getResult();
175+
if (!result.isOK()) {
176+
throw new CoreException(result);
177+
}
178+
}
179+
}
180+
181+
private void assertContentAccessibleOrNotFound(IFile file) {
182+
try (InputStream contents = file.getContents(false)) {
183+
contents.transferTo(OutputStream.nullOutputStream());
184+
} catch (IOException e) {
185+
throw new AssertionError(e);
186+
} catch (CoreException e) {
187+
switch (e.getStatus().getCode()) {
188+
case IResourceStatus.RESOURCE_NOT_LOCAL:
189+
case IResourceStatus.RESOURCE_NOT_FOUND:
190+
case IResourceStatus.FAILED_READ_LOCAL:
191+
case IResourceStatus.OUT_OF_SYNC_LOCAL:
192+
break;
193+
default:
194+
throw new AssertionError(e);
195+
}
196+
}
197+
try (InputStream contents = file.getContents(true)) {
198+
contents.transferTo(OutputStream.nullOutputStream());
199+
} catch (IOException e) {
200+
throw new AssertionError(e);
201+
} catch (CoreException e) {
202+
switch (e.getStatus().getCode()) {
203+
case IResourceStatus.RESOURCE_NOT_LOCAL:
204+
case IResourceStatus.RESOURCE_NOT_FOUND:
205+
case IResourceStatus.FAILED_READ_LOCAL:
206+
break;
207+
default:
208+
throw new AssertionError(e);
209+
}
210+
}
211+
}
212+
128213
}

0 commit comments

Comments
 (0)