Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 20 additions & 11 deletions src/libraries/Common/src/Interop/Unix/Interop.IOErrors.cs
Original file line number Diff line number Diff line change
Expand Up @@ -104,23 +104,39 @@ internal static TSafeHandle CheckIo<TSafeHandle>(TSafeHandle handle, string? pat
return handle;
}

internal static Exception GetExceptionForIoErrno(ErrorInfo errorInfo) =>
GetExceptionForIoErrnoCore(errorInfo, path: null, isDirError: false);

/// <summary>
/// Gets an Exception to represent the supplied error info.
/// </summary>
/// <param name="errorInfo">The error info</param>
/// <param name="path">The path with which this error is associated. This may be null.</param>
/// <param name="isDirError">true if error is caused by a directory issue.</param>
/// <returns></returns>
internal static Exception GetExceptionForIoErrno(ErrorInfo errorInfo, string? path = null, bool isDirError = false)
internal static Exception GetExceptionForIoErrno(ErrorInfo errorInfo, string? path, bool isDirError = false)
{
// Keep path/directory operations separate from GetExceptionForIoErrnoCore to allow better trimming:
// pathless callers do not pull in Path and Directory APIs.
// For Windows compatibility, throw DirectoryNotFoundException instead of FileNotFoundException
// when the parent folder does not exist.
if (errorInfo.Error == Error.ENOENT && !isDirError && path is not null)
{
string? parentPath = Path.GetDirectoryName(Path.TrimEndingDirectorySeparator(path));
isDirError = !Directory.Exists(parentPath);
}

return GetExceptionForIoErrnoCore(errorInfo, path, isDirError);
}

private static Exception GetExceptionForIoErrnoCore(ErrorInfo errorInfo, string? path, bool isDirError)
{
// Translate the errno into a known set of exception types. For cases where multiple errnos map
// to the same exception type, include an inner exception with the details.
switch (errorInfo.Error)
{
case Error.ENOENT:
// For Windows compatibility, throw DirectoryNotFoundException instead of FileNotFoundException
// when the parent folder does not exist.
if (!isDirError && (path is null || ParentDirectoryExists(path)))
if (!isDirError)
{
return !string.IsNullOrEmpty(path) ?
new FileNotFoundException(SR.Format(SR.IO_FileNotFound_FileName, path), path) :
Expand Down Expand Up @@ -170,13 +186,6 @@ internal static Exception GetExceptionForIoErrno(ErrorInfo errorInfo, string? pa

default:
return GetIOException(errorInfo, path);

static bool ParentDirectoryExists(string fullPath)
{
string? parentPath = Path.GetDirectoryName(Path.TrimEndingDirectorySeparator(fullPath));

return Directory.Exists(parentPath);
}
}
}

Expand Down
Loading