-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Description
Background and motivation
The DirectoryNotFoundException
type does not provide any way for the thrower to specify the actual directory path in a machine-readable way such that any downstream/consuming program code that catches the exception can isolate the directory-path; currently we're forced to try to parse the human-readable .Message
property which, additionally, might be a localized string and thus impossible to reliably process under all circumstances, which is important in error-handling functions.
It's also inconsistent with how FileNotFoundException
has a String FileName { get; }
property.
I did search through all 7 pages of existing Issues in the runtime repo matching "DirectoryNotFoundException
" - none of them are a request to add a directory-path property to the exception.
API Proposal
namespace System.IO;
public class DirectoryNotFoundException : IOException
{
public DirectoryNotFoundException (string? message, string? directoryPath, Exception? innerException)
: this(message: message, innerException: innerException)
{
this.DirectoryPath = directoryPath;
}
public DirectoryNotFoundException (string? message, string? directoryPath)
: this(message: message)
{
this.DirectoryPath = directoryPath;
}
public string? DirectoryPath { get; }
}
API Usage
public static void ExampleMethodThatCopiesFilesAround(DirectoryInfo source, DirectoryInfo dest)
{
if (!source.Exists) throw new DirectoryNotFoundException(message: "Source directory does not exist.", directoryPath: source.FullName);
if (!dest.Exists) throw new DirectoryNotFoundException(message: "Destination directory does not exist.", directoryPath: dest.FullName);
foreach (FileInfo fi in source.GetFiles())
{
// etc...
}
}
//
using Microsoft.Extensions.Logging;
public void ConsumingMethodWithLogger()
{
try
{
ExampleMethodThatCopiesFilesAround(source: foo, dest: bar);
}
catch (DirectoryNotFoundException dEx)
{
using (this.logger.BeginScope("DirectoryPath", dEx.DirectoryPath))
{
this.logger.LogError(exception: dEx, message: "Directory not found: {DirectoryPath}", dEx.DirectoryPath);
}
}
}
Alternative Designs
No response
Risks
This change involves only adding additional (and entirely optional and nullable) constructor overloads and properties.
It's possible that there exists user-code that subclasses DirectoryNotFoundException
to add their own property for the missing directory's full-path, but I assume this wouldn't be an ABI breaking change because user subclasses would still be using a different class member "slot" (right?)