Skip to content

Commit 8c49f31

Browse files
committed
Do not throw RuntimeException from IFile.getContents(false) #2290
1 parent b7cb30f commit 8c49f31

File tree

2 files changed

+79
-1
lines changed

2 files changed

+79
-1
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: 75 additions & 1 deletion
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,22 +25,27 @@
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;
3845
import org.junit.jupiter.api.extension.ExtendWith;
3946

4047
@ExtendWith(WorkspaceResetExtension.class)
4148
public class IFileTest {
42-
4349
/**
4450
* Bug states that the error code in the CoreException which is thrown when
4551
* you try to create a file in a read-only folder on Linux should be
@@ -125,4 +131,72 @@ public void testBug43936() throws CoreException {
125131
project.setDescription(desc, createTestMonitor());
126132
}
127133

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

0 commit comments

Comments
 (0)