如何处理导致异常的WinRT异常?
如果Windows运行时类型引发COM错误,.NET似乎经常(或总是)将此错误包装到Exception
实例中。 错误消息包括COM HRESULT错误代码。 例如,当使用AES-CBC的新Cryptographic API时,错误的缓冲区长度会导致Exception
,并显示消息“提供的用户缓冲区对于请求的操作无效( Exception from HRESULT: 0x800706F8
)”。
那么,我们应该如何处理这些例外? 我们是否应该从异常中读取HRESULT
代码以获得一个想法是什么样的异常? 在经典的.NET中,我会得到一个CryptographicException
,我可以用它来区分加密错误和其他错误。
另一个我不明白的地方是,Microsoft代码质量规则声明一个人不应该抛出异常,但总是派生类型。 原因是没有人应该强制捕获一般Exception
,以捕获更多致命异常,如OutOfMemoryException
。 另一条规则是,永远不应该在图书馆中捕捉到Exceptio
。 如果我们被迫在Windows Store应用程序或WinRT库中捕获Exception
,我们如何才能遵循这些策略?
顺便说一下:Clemens Vasters在他的博客中显示我们如何捕捉异常,同时避免发生致命异常。 我认为捕捉Exception
不再是坏代码。
可以通过打开HRESULT来捕获Exception
,处理特定的错误,并且如果错误是“意外的”,则重新抛出Exception
。 例如,
try
{
// ...
}
catch (Exception ex)
{
switch (ex->HResult)
{
case E_INVALID_USER_BUFFER: // 0x800706f8
// handle invalid buffer case...
break;
default:
// Unexpected exception; re-throw:
throw;
}
}
(我会注意到,提供一个无效的缓冲区听起来更像是一个逻辑错误,而不是运行时错误,所以我想知道这个特定的异常是否应该被捕获。)
或者,更通用的解决方案是编写一个函数或一组处理已知HRESULT Exception
的函数,并重新引发更具体的异常。 例如,
static void HandleKnownExceptions(Action f)
{
try
{
f();
}
catch (Exception ex)
{
// Detect expected HRESULTs and throw the more-specific exception
// type for each.
}
}
这两种方法在C ++和C#中都同样适用。
请注意,不一定是由平台或其他组件直接抛出Exception
。 在Windows运行时ABI层,没有例外:通过HRESULT在ABI边界上报告所有错误。 CLR将一些已知的HRESULT转换为更具体的异常类型,但不能执行一般翻译。
上一篇: How to handle WinRT exceptions that result in Exception?
下一篇: How to upgrade Qt installed in linux from one version to higher