我们在生产中的以下代码中遇到错误。我们正在努力确保我们有良好的错误,这使我们能够轻松地解决问题。
在这种情况下,代码……并不是很有帮助。为什么?看看代码,我将在下面解释原因……
public CodecIndexInput(FileInfo file, Func<Stream, Stream> applyCodecs)
{
try
{
this.file = file;
this.applyCodecs = applyCodecs;
fileHandle = Win32NativeFileMethods.CreateFile(file.FullName,
Win32NativeFileAccess.GenericRead,
Win32NativeFileShare.Read | Win32NativeFileShare.Write | Win32NativeFileShare.Delete,
IntPtr.Zero,
Win32NativeFileCreationDisposition.OpenExisting,
Win32NativeFileAttributes.RandomAccess,
IntPtr.Zero);
if (fileHandle.IsInvalid)
{
const int ERROR_FILE_NOT_FOUND = 2;
if (Marshal.GetLastWin32Error() == ERROR_FILE_NOT_FOUND)
throw new FileNotFoundException(file.FullName);
throw new Win32Exception();
}
mmf = Win32MemoryMapNativeMethods.CreateFileMapping(fileHandle.DangerousGetHandle(), IntPtr.Zero, Win32MemoryMapNativeMethods.FileMapProtection.PageReadonly,
0, 0, null);
if (mmf == IntPtr.Zero)
{
throw new Win32Exception();
}
basePtr = Win32MemoryMapNativeMethods.MapViewOfFileEx(mmf,
Win32MemoryMapNativeMethods.NativeFileMapAccessType.Read,
0, 0, UIntPtr.Zero, null);
if (basePtr == null)
throw new Win32Exception();
stream = applyCodecs(new MmapStream(basePtr, file.Length));
}
catch (Exception)
{
Dispose(false);
throw;
}
}
你看见了吗?
此代码有多个位置可以引发 Win32Exception。问题在于,此模式下的 Win32Exception 几乎只是一段代码,我们在该方法中有多个位置可以抛出。
发生这种情况时,如果我们没有部署 PDB 文件,我们无法仅从堆栈跟踪(没有行号)知道是哪个方法调用导致了错误。这会在事后导致一些混乱。
我们通过为每个选项添加描述文本来解决这个问题,包括让我们知道发生了什么的附加信息。特别是,我们不仅包括失败的操作,更重要的是,我们包括失败的文件。