1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2024-06-26 07:03:22 +00:00

Some further improvemnets to mount error handling

- Correctly handle FileOperationExceptions for the root mount.
 - Remove some checks from MountWrapper: Mount/WritableMount should do
   these already!
 - Normalise file paths, always using a '/'.
This commit is contained in:
Jonathan Coates 2022-12-10 12:54:49 +00:00
parent 367773e173
commit 18fbd96c10
No known key found for this signature in database
GPG Key ID: B9E431FF07C98D06
4 changed files with 15 additions and 25 deletions

View File

@ -32,7 +32,8 @@ public interface WritableMount extends Mount {
void makeDirectory(String path) throws IOException; void makeDirectory(String path) throws IOException;
/** /**
* Deletes a directory at a given path inside the virtual file system. * Deletes a directory at a given path inside the virtual file system. If the file does not exist, this method
* should do nothing.
* *
* @param path A file path in normalised format, relative to the mount location. ie: "programs/myoldprograms". * @param path A file path in normalised format, relative to the mount location. ie: "programs/myoldprograms".
* @throws IOException If the file does not exist or could not be deleted. * @throws IOException If the file does not exist or could not be deleted.

View File

@ -5,6 +5,7 @@
*/ */
package dan200.computercraft.core.filesystem; package dan200.computercraft.core.filesystem;
import com.google.common.base.Joiner;
import dan200.computercraft.api.filesystem.FileAttributes; import dan200.computercraft.api.filesystem.FileAttributes;
import dan200.computercraft.api.filesystem.FileOperationException; import dan200.computercraft.api.filesystem.FileOperationException;
import dan200.computercraft.api.filesystem.Mount; import dan200.computercraft.api.filesystem.Mount;
@ -104,7 +105,7 @@ public SeekableByteChannel openForRead(String path) throws FileOperationExceptio
protected FileOperationException remapException(String fallbackPath, IOException exn) { protected FileOperationException remapException(String fallbackPath, IOException exn) {
return exn instanceof FileSystemException fsExn return exn instanceof FileSystemException fsExn
? remapException(fallbackPath, fsExn) ? remapException(fallbackPath, fsExn)
: new FileOperationException(fallbackPath, exn.getMessage() == null ? "Operation failed" : exn.getMessage()); : new FileOperationException(fallbackPath, exn.getMessage() == null ? "Access denied" : exn.getMessage());
} }
/** /**
@ -123,7 +124,7 @@ protected FileOperationException remapException(String fallbackPath, FileSystemE
var failedPath = Path.of(failedFile); var failedPath = Path.of(failedFile);
return failedPath.startsWith(root) return failedPath.startsWith(root)
? new FileOperationException(root.relativize(failedPath).toString(), reason) ? new FileOperationException(Joiner.on('/').join(root.relativize(failedPath)), reason)
: new FileOperationException(fallbackPath, reason); : new FileOperationException(fallbackPath, reason);
} }

View File

@ -79,7 +79,7 @@ public boolean exists(String path) throws FileSystemException {
public boolean isDirectory(String path) throws FileSystemException { public boolean isDirectory(String path) throws FileSystemException {
path = toLocal(path); path = toLocal(path);
try { try {
return mount.exists(path) && mount.isDirectory(path); return mount.isDirectory(path);
} catch (IOException e) { } catch (IOException e) {
throw localExceptionOf(path, e); throw localExceptionOf(path, e);
} }
@ -101,8 +101,7 @@ public void list(String path, List<String> contents) throws FileSystemException
public long getSize(String path) throws FileSystemException { public long getSize(String path) throws FileSystemException {
path = toLocal(path); path = toLocal(path);
try { try {
if (!mount.exists(path)) throw localExceptionOf(path, "No such file"); return mount.getSize(path);
return mount.isDirectory(path) ? 0 : mount.getSize(path);
} catch (IOException e) { } catch (IOException e) {
throw localExceptionOf(path, e); throw localExceptionOf(path, e);
} }
@ -111,7 +110,6 @@ public long getSize(String path) throws FileSystemException {
public BasicFileAttributes getAttributes(String path) throws FileSystemException { public BasicFileAttributes getAttributes(String path) throws FileSystemException {
path = toLocal(path); path = toLocal(path);
try { try {
if (!mount.exists(path)) throw localExceptionOf(path, "No such file");
return mount.getAttributes(path); return mount.getAttributes(path);
} catch (IOException e) { } catch (IOException e) {
throw localExceptionOf(path, e); throw localExceptionOf(path, e);
@ -121,11 +119,7 @@ public BasicFileAttributes getAttributes(String path) throws FileSystemException
public SeekableByteChannel openForRead(String path) throws FileSystemException { public SeekableByteChannel openForRead(String path) throws FileSystemException {
path = toLocal(path); path = toLocal(path);
try { try {
if (mount.exists(path) && !mount.isDirectory(path)) { return mount.openForRead(path);
return mount.openForRead(path);
} else {
throw localExceptionOf(path, "No such file");
}
} catch (IOException e) { } catch (IOException e) {
throw localExceptionOf(path, e); throw localExceptionOf(path, e);
} }
@ -136,11 +130,7 @@ public void makeDirectory(String path) throws FileSystemException {
path = toLocal(path); path = toLocal(path);
try { try {
if (mount.exists(path)) { writableMount.makeDirectory(path);
if (!mount.isDirectory(path)) throw localExceptionOf(path, "File exists");
} else {
writableMount.makeDirectory(path);
}
} catch (IOException e) { } catch (IOException e) {
throw localExceptionOf(path, e); throw localExceptionOf(path, e);
} }
@ -151,9 +141,7 @@ public void delete(String path) throws FileSystemException {
path = toLocal(path); path = toLocal(path);
try { try {
if (mount.exists(path)) { writableMount.delete(path);
writableMount.delete(path);
}
} catch (IOException e) { } catch (IOException e) {
throw localExceptionOf(path, e); throw localExceptionOf(path, e);
} }
@ -224,8 +212,8 @@ private String toLocal(String path) {
return FileSystem.toLocal(path, location); return FileSystem.toLocal(path, location);
} }
private FileSystemException localExceptionOf(@Nullable String localPath, IOException e) { private FileSystemException localExceptionOf(String localPath, IOException e) {
if (!location.isEmpty() && e instanceof FileOperationException ex) { if (e instanceof FileOperationException ex) {
if (ex.getFilename() != null) return localExceptionOf(ex.getFilename(), FileSystemException.getMessage(ex)); if (ex.getFilename() != null) return localExceptionOf(ex.getFilename(), FileSystemException.getMessage(ex));
} }
@ -233,8 +221,8 @@ private FileSystemException localExceptionOf(@Nullable String localPath, IOExcep
// This error will contain the absolute path, leaking information about where MC is installed. We drop that, // This error will contain the absolute path, leaking information about where MC is installed. We drop that,
// just taking the reason. We assume that the error refers to the input path. // just taking the reason. We assume that the error refers to the input path.
var message = ex.getReason(); var message = ex.getReason();
if (message == null) message = "Failed"; if (message == null) message = "Access denied";
return localPath == null ? new FileSystemException(message) : localExceptionOf(localPath, message); return localExceptionOf(localPath, message);
} }
return FileSystemException.of(e); return FileSystemException.of(e);

View File

@ -183,7 +183,7 @@ public SeekableByteChannel openForWrite(String path) throws FileOperationExcepti
} }
@Override @Override
public SeekableByteChannel openForAppend(String path) throws IOException { public SeekableByteChannel openForAppend(String path) throws FileOperationException {
create(); create();
var file = resolvePath(path); var file = resolvePath(path);