|
19 | 19 | import static java.nio.charset.StandardCharsets.ISO_8859_1; |
20 | 20 |
|
21 | 21 | import com.google.common.base.Preconditions; |
| 22 | +import com.google.common.collect.ImmutableMap; |
22 | 23 | import com.google.common.collect.Lists; |
23 | 24 | import com.google.common.io.ByteSource; |
24 | 25 | import com.google.common.io.CharStreams; |
|
41 | 42 | import java.util.Collection; |
42 | 43 | import java.util.Iterator; |
43 | 44 | import java.util.List; |
| 45 | +import java.util.Map; |
44 | 46 | import javax.annotation.Nullable; |
45 | 47 |
|
46 | 48 | /** This interface models a file system. */ |
@@ -812,6 +814,25 @@ public java.nio.file.Path getNioPath(PathFragment path) { |
812 | 814 | "getNioPath() not supported for " + getClass().getName()); |
813 | 815 | } |
814 | 816 |
|
| 817 | + // Mapping from FileSystemException reason strings on various platforms to the corresponding Unix |
| 818 | + // error message that Bazel's own filesystem implementations produce. Bazel forces the root locale |
| 819 | + // for the JVM, so the error messages should be stable per OS. |
| 820 | + // This map is best-effort and almost certainly incomplete, especially on Windows. |
| 821 | + private static final Map<String, String> reasonToUnixError = |
| 822 | + ImmutableMap.of( |
| 823 | + // Unix |
| 824 | + "Is a directory", |
| 825 | + ERR_IS_DIRECTORY, |
| 826 | + "Not a directory", |
| 827 | + ERR_NOT_A_DIRECTORY, |
| 828 | + "Directory not empty", |
| 829 | + ERR_DIRECTORY_NOT_EMPTY, |
| 830 | + // Windows |
| 831 | + // https://github.com/bazelbuild/bazel/pull/27458#discussion_r2478544279 |
| 832 | + // https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499- |
| 833 | + "The directory is not empty.", |
| 834 | + ERR_DIRECTORY_NOT_EMPTY); |
| 835 | + |
815 | 836 | /** |
816 | 837 | * Translates common java.nio.file IOExceptions into the equivalent java.io IOExceptions with |
817 | 838 | * consistent error messages. |
@@ -845,18 +866,12 @@ protected static IOException translateNioToIoException(PathFragment path, IOExce |
845 | 866 | case NotDirectoryException unused -> new IOException(prefix + ERR_NOT_A_DIRECTORY, e); |
846 | 867 | case NotLinkException unused -> new NotASymlinkException(path, e); |
847 | 868 | // Rewrite exception messages to be identical to the ones produced by the native Unix |
848 | | - // filesystem implementation. Bazel forces the root locale for the JVM, so the error messages |
849 | | - // should be stable. Some of the exceptions caught above can also appear as untyped |
850 | | - // FileSystemExceptions, so we need to catch those as well. |
851 | | - case FileSystemException unused |
852 | | - when fileSystemException.getReason().equals("Is a directory") -> |
853 | | - new IOException(prefix + ERR_IS_DIRECTORY, e); |
854 | | - case FileSystemException unused |
855 | | - when fileSystemException.getReason().equals("Not a directory") -> |
856 | | - new IOException(prefix + ERR_NOT_A_DIRECTORY, e); |
857 | | - case FileSystemException unused |
858 | | - when fileSystemException.getReason().equals("Directory not empty") -> |
859 | | - new IOException(prefix + ERR_DIRECTORY_NOT_EMPTY, e); |
| 869 | + // filesystem implementation. Some of the exceptions caught above can also appear as untyped |
| 870 | + // FileSystemExceptions and are thus included in reasonToUnixError. |
| 871 | + case FileSystemException fse -> { |
| 872 | + String unixError = reasonToUnixError.get(fse.getReason()); |
| 873 | + yield unixError != null ? new IOException(prefix + unixError, e) : fileSystemException; |
| 874 | + } |
860 | 875 | default -> fileSystemException; |
861 | 876 | }; |
862 | 877 | } |
|
0 commit comments