mirror of
				https://github.com/SquidDev-CC/CC-Tweaked
				synced 2025-10-31 05:33:00 +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:
		| @@ -32,7 +32,8 @@ public interface WritableMount extends Mount { | ||||
|     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". | ||||
|      * @throws IOException If the file does not exist or could not be deleted. | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
|  */ | ||||
| package dan200.computercraft.core.filesystem; | ||||
| 
 | ||||
| import com.google.common.base.Joiner; | ||||
| import dan200.computercraft.api.filesystem.FileAttributes; | ||||
| import dan200.computercraft.api.filesystem.FileOperationException; | ||||
| import dan200.computercraft.api.filesystem.Mount; | ||||
| @@ -104,7 +105,7 @@ public class FileMount implements Mount { | ||||
|     protected FileOperationException remapException(String fallbackPath, IOException exn) { | ||||
|         return exn instanceof FileSystemException 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 @@ public class FileMount implements Mount { | ||||
| 
 | ||||
|         var failedPath = Path.of(failedFile); | ||||
|         return failedPath.startsWith(root) | ||||
|             ? new FileOperationException(root.relativize(failedPath).toString(), reason) | ||||
|             ? new FileOperationException(Joiner.on('/').join(root.relativize(failedPath)), reason) | ||||
|             : new FileOperationException(fallbackPath, reason); | ||||
|     } | ||||
| 
 | ||||
|   | ||||
| @@ -79,7 +79,7 @@ class MountWrapper { | ||||
|     public boolean isDirectory(String path) throws FileSystemException { | ||||
|         path = toLocal(path); | ||||
|         try { | ||||
|             return mount.exists(path) && mount.isDirectory(path); | ||||
|             return mount.isDirectory(path); | ||||
|         } catch (IOException e) { | ||||
|             throw localExceptionOf(path, e); | ||||
|         } | ||||
| @@ -101,8 +101,7 @@ class MountWrapper { | ||||
|     public long getSize(String path) throws FileSystemException { | ||||
|         path = toLocal(path); | ||||
|         try { | ||||
|             if (!mount.exists(path)) throw localExceptionOf(path, "No such file"); | ||||
|             return mount.isDirectory(path) ? 0 : mount.getSize(path); | ||||
|             return mount.getSize(path); | ||||
|         } catch (IOException e) { | ||||
|             throw localExceptionOf(path, e); | ||||
|         } | ||||
| @@ -111,7 +110,6 @@ class MountWrapper { | ||||
|     public BasicFileAttributes getAttributes(String path) throws FileSystemException { | ||||
|         path = toLocal(path); | ||||
|         try { | ||||
|             if (!mount.exists(path)) throw localExceptionOf(path, "No such file"); | ||||
|             return mount.getAttributes(path); | ||||
|         } catch (IOException e) { | ||||
|             throw localExceptionOf(path, e); | ||||
| @@ -121,11 +119,7 @@ class MountWrapper { | ||||
|     public SeekableByteChannel openForRead(String path) throws FileSystemException { | ||||
|         path = toLocal(path); | ||||
|         try { | ||||
|             if (mount.exists(path) && !mount.isDirectory(path)) { | ||||
|                 return mount.openForRead(path); | ||||
|             } else { | ||||
|                 throw localExceptionOf(path, "No such file"); | ||||
|             } | ||||
|             return mount.openForRead(path); | ||||
|         } catch (IOException e) { | ||||
|             throw localExceptionOf(path, e); | ||||
|         } | ||||
| @@ -136,11 +130,7 @@ class MountWrapper { | ||||
| 
 | ||||
|         path = toLocal(path); | ||||
|         try { | ||||
|             if (mount.exists(path)) { | ||||
|                 if (!mount.isDirectory(path)) throw localExceptionOf(path, "File exists"); | ||||
|             } else { | ||||
|                 writableMount.makeDirectory(path); | ||||
|             } | ||||
|             writableMount.makeDirectory(path); | ||||
|         } catch (IOException e) { | ||||
|             throw localExceptionOf(path, e); | ||||
|         } | ||||
| @@ -151,9 +141,7 @@ class MountWrapper { | ||||
| 
 | ||||
|         path = toLocal(path); | ||||
|         try { | ||||
|             if (mount.exists(path)) { | ||||
|                 writableMount.delete(path); | ||||
|             } | ||||
|             writableMount.delete(path); | ||||
|         } catch (IOException e) { | ||||
|             throw localExceptionOf(path, e); | ||||
|         } | ||||
| @@ -224,8 +212,8 @@ class MountWrapper { | ||||
|         return FileSystem.toLocal(path, location); | ||||
|     } | ||||
| 
 | ||||
|     private FileSystemException localExceptionOf(@Nullable String localPath, IOException e) { | ||||
|         if (!location.isEmpty() && e instanceof FileOperationException ex) { | ||||
|     private FileSystemException localExceptionOf(String localPath, IOException e) { | ||||
|         if (e instanceof FileOperationException ex) { | ||||
|             if (ex.getFilename() != null) return localExceptionOf(ex.getFilename(), FileSystemException.getMessage(ex)); | ||||
|         } | ||||
| 
 | ||||
| @@ -233,8 +221,8 @@ class MountWrapper { | ||||
|             // 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. | ||||
|             var message = ex.getReason(); | ||||
|             if (message == null) message = "Failed"; | ||||
|             return localPath == null ? new FileSystemException(message) : localExceptionOf(localPath, message); | ||||
|             if (message == null) message = "Access denied"; | ||||
|             return localExceptionOf(localPath, message); | ||||
|         } | ||||
| 
 | ||||
|         return FileSystemException.of(e); | ||||
|   | ||||
| @@ -183,7 +183,7 @@ public class WritableFileMount extends FileMount implements WritableMount { | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public SeekableByteChannel openForAppend(String path) throws IOException { | ||||
|     public SeekableByteChannel openForAppend(String path) throws FileOperationException { | ||||
|         create(); | ||||
| 
 | ||||
|         var file = resolvePath(path); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Jonathan Coates
					Jonathan Coates